summaryrefslogtreecommitdiffstats
path: root/src/render/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/backend')
-rw-r--r--src/render/backend/commandthread.cpp195
-rw-r--r--src/render/backend/commandthread_p.h115
-rw-r--r--src/render/backend/glcommands.cpp67
-rw-r--r--src/render/backend/glcommands_p.h89
-rw-r--r--src/render/backend/openglvertexarrayobject.cpp160
-rw-r--r--src/render/backend/openglvertexarrayobject_p.h110
-rw-r--r--src/render/backend/render-backend.pri26
-rw-r--r--src/render/backend/rendercommand.cpp76
-rw-r--r--src/render/backend/rendercommand_p.h130
-rw-r--r--src/render/backend/renderconfiguration.cpp54
-rw-r--r--src/render/backend/renderconfiguration_p.h72
-rw-r--r--src/render/backend/renderer.cpp2067
-rw-r--r--src/render/backend/renderer_p.h405
-rw-r--r--src/render/backend/renderercache_p.h87
-rw-r--r--src/render/backend/renderqueue.cpp133
-rw-r--r--src/render/backend/renderqueue_p.h102
-rw-r--r--src/render/backend/renderview.cpp1108
-rw-r--r--src/render/backend/renderview_p.h392
-rw-r--r--src/render/backend/renderviewbuilder.cpp672
-rw-r--r--src/render/backend/renderviewbuilder_p.h149
-rw-r--r--src/render/backend/shaderparameterpack.cpp100
-rw-r--r--src/render/backend/shaderparameterpack_p.h145
-rw-r--r--src/render/backend/shadervariables_p.h152
23 files changed, 2 insertions, 6604 deletions
diff --git a/src/render/backend/commandthread.cpp b/src/render/backend/commandthread.cpp
deleted file mode 100644
index 387fc1113..000000000
--- a/src/render/backend/commandthread.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/****************************************************************************
-**
-** 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: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 "commandthread_p.h"
-#include <Qt3DRender/private/glcommands_p.h>
-#include <Qt3DRender/private/offscreensurfacehelper_p.h>
-#include <Qt3DRender/private/graphicscontext_p.h>
-#include <Qt3DRender/private/shadercache_p.h>
-#include <QOpenGLContext>
-#include <QOffscreenSurface>
-#include <QDebug>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-
-namespace Render {
-
-CommandThread::CommandThread(Renderer *renderer)
- : QThread()
- , m_renderer(renderer)
- , m_waitForStartSemaphore(0)
- , m_initializedSemaphore(0)
- , m_commandRequestedSemaphore(0)
- , m_commandExecutionSemaphore(0)
- , m_mainContext(nullptr)
- , m_shaderCache(nullptr)
- , m_offsreenSurfaceHelper(nullptr)
- , m_currentCommand(nullptr)
- , m_running(0)
-{
-}
-
-CommandThread::~CommandThread()
-{
-}
-
-void CommandThread::setShaderCache(ShaderCache *shaderCache)
-{
- m_shaderCache = shaderCache;
-}
-
-// Called by RenderThread or MainThread (Scene3d)
-void CommandThread::initialize(QOpenGLContext *mainContext, OffscreenSurfaceHelper *offsreenSurfaceHelper)
-{
- // Start the thread
- start();
-
- // Wait for thread to be started
- m_waitForStartSemaphore.acquire();
-
- m_mainContext = mainContext;
- m_offsreenSurfaceHelper = offsreenSurfaceHelper;
- Q_ASSERT(m_mainContext && offsreenSurfaceHelper);
- m_running.fetchAndStoreOrdered(1);
-
- // Allow thread to proceed
- m_initializedSemaphore.release();
-}
-
-// Called by RenderThread or MainThread (Scene3D)
-void CommandThread::shutdown()
-{
- m_running.fetchAndStoreOrdered(0);
-
- // Unblock thread
- m_commandRequestedSemaphore.release(1);
-
- // Wait for thread to exit
- wait();
-
- // Reset semaphores (in case we ever want to restart)
- m_waitForStartSemaphore.acquire(m_waitForStartSemaphore.available());
- m_initializedSemaphore.acquire(m_initializedSemaphore.available());
- m_commandRequestedSemaphore.acquire(m_commandRequestedSemaphore.available());
- m_commandExecutionSemaphore.acquire(m_commandExecutionSemaphore.available());
- m_localContext.reset();
-}
-
-// Any thread can call this, this is a blocking command
-void CommandThread::executeCommand(GLCommand *command)
-{
- if (!isRunning())
- return;
-
- // We lock to prevent any other call to executeCommand to be executed
- // before we have received the result of our command
- m_blockingCallerMutex.lock();
-
- // Store command to be executed
- m_currentCommand = command;
-
- // Allow thread to proceed and execute command
- m_commandRequestedSemaphore.release();
-
- // Wait for thread to be done
- m_commandExecutionSemaphore.acquire();
-
- // Reset command
- m_currentCommand = nullptr;
-
- // Unlock blocking semaphore so that other calls to executeCommand
- // can proceed
- m_blockingCallerMutex.unlock();
-}
-
-void CommandThread::run()
-{
- // Allow initialize to proceed
- m_waitForStartSemaphore.release();
-
- // Wait for initialize to be completed
- m_initializedSemaphore.acquire();
-
- Q_ASSERT(m_mainContext && m_shaderCache);
-
- // Initialize shared context and resources for the thread
- m_localContext.reset(new QOpenGLContext());
- m_localContext->setShareContext(m_mainContext);
- m_localContext->create();
-
- // Initialize GraphicsContext
- m_graphicsContext.reset(new GraphicsContext());
- m_graphicsContext->setShaderCache(m_shaderCache);
- m_graphicsContext->setOpenGLContext(m_localContext.data());
-
- bool initialized = false;
- while (true) {
-
- // Wait for command
- m_commandRequestedSemaphore.acquire();
-
- // Are we still running?
- if (!m_running.load()) {
- m_graphicsContext->doneCurrent();
- // to prevent executeCommand being locked
- m_commandExecutionSemaphore.release();
- break;
- }
-
- if (Q_UNLIKELY(!initialized)) {
- QOffscreenSurface *offscreenSurface = m_offsreenSurfaceHelper->offscreenSurface();
- Q_ASSERT(offscreenSurface);
- m_graphicsContext->makeCurrent(offscreenSurface);
- initialized = true;
- }
-
- m_currentCommand->execute(m_renderer, m_graphicsContext.data());
-
- // Allow caller to proceed as we are done with the command
- m_commandExecutionSemaphore.release();
- }
-}
-
-} // Render
-
-} // Qt3DRender
-
-QT_END_NAMESPACE
diff --git a/src/render/backend/commandthread_p.h b/src/render/backend/commandthread_p.h
deleted file mode 100644
index 0508675c4..000000000
--- a/src/render/backend/commandthread_p.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/****************************************************************************
-**
-** 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: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 QT3DRENDER_RENDER_COMMANDTHREAD_P_H
-#define QT3DRENDER_RENDER_COMMANDTHREAD_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/QThread>
-#include <QtCore/QSemaphore>
-#include <QtCore/QMutex>
-
-QT_BEGIN_NAMESPACE
-
-class QOpenGLContext;
-
-namespace Qt3DRender {
-
-namespace Render {
-
-class Renderer;
-class GLCommand;
-class OffscreenSurfaceHelper;
-class GraphicsContext;
-class ShaderCache;
-
-class CommandThread : public QThread
-{
- Q_OBJECT
-public:
- explicit CommandThread(Renderer *renderer);
- ~CommandThread();
-
- Render::Renderer* renderer() const { return m_renderer; }
-
- void setShaderCache(ShaderCache *shaderCache);
- ShaderCache *shaderCache() const { return m_shaderCache; }
-
- void initialize(QOpenGLContext *mainContext, OffscreenSurfaceHelper *offsreenSurfaceHelper);
- void shutdown();
-
- void executeCommand(GLCommand *command);
-
-private:
- void run() override;
- void executeCommandInternal(Qt3DRender::Render::GLCommand *command);
-
-private:
- Renderer* m_renderer;
- QSemaphore m_waitForStartSemaphore;
- QSemaphore m_initializedSemaphore;
- QSemaphore m_commandRequestedSemaphore;
- QSemaphore m_commandExecutionSemaphore;
- QMutex m_blockingCallerMutex;
- QOpenGLContext *m_mainContext;
- ShaderCache *m_shaderCache;
- OffscreenSurfaceHelper *m_offsreenSurfaceHelper;
- QScopedPointer<QOpenGLContext> m_localContext;
- QScopedPointer<GraphicsContext> m_graphicsContext;
- GLCommand *m_currentCommand;
- QAtomicInt m_running;
-};
-
-} // Render
-
-} // Qt3DRender
-
-QT_END_NAMESPACE
-
-#endif // QT3DRENDER_RENDER_COMMANDTHREAD_P_H
diff --git a/src/render/backend/glcommands.cpp b/src/render/backend/glcommands.cpp
deleted file mode 100644
index fd7ee9fe8..000000000
--- a/src/render/backend/glcommands.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** 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: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 "glcommands_p.h"
-#include <Qt3DRender/private/renderer_p.h>
-#include <Qt3DRender/private/graphicscontext_p.h>
-#include <Qt3DRender/private/nodemanagers_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-
-namespace Render {
-
-LoadShaderCommand::LoadShaderCommand(Shader *shader)
- : m_shader(shader)
-{
- Q_ASSERT(m_shader);
-}
-
-void LoadShaderCommand::execute(Renderer *renderer, GraphicsContext *ctx)
-{
- NodeManagers *nodeManagers = renderer->nodeManagers();
- ctx->loadShader(m_shader, nodeManagers->shaderManager());
-}
-
-} // Render
-
-} // Qt3DRender
-
-QT_END_NAMESPACE
diff --git a/src/render/backend/glcommands_p.h b/src/render/backend/glcommands_p.h
deleted file mode 100644
index 5ed360759..000000000
--- a/src/render/backend/glcommands_p.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-**
-** 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: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 QT3DRENDER_RENDER_GLCOMMANDS_P_H
-#define QT3DRENDER_RENDER_GLCOMMANDS_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 <Qt3DRender/qt3drender_global.h>
-
-QT_BEGIN_NAMESPACE
-
-
-namespace Qt3DRender {
-
-namespace Render {
-
-class GraphicsContext;
-class Renderer;
-class Shader;
-
-class GLCommand
-{
-public:
- virtual void execute(Renderer *renderer, GraphicsContext *ctx) = 0;
-};
-
-class Q_AUTOTEST_EXPORT LoadShaderCommand : public GLCommand
-{
-public:
- explicit LoadShaderCommand(Shader *shader);
- Shader *shader() const { return m_shader; }
- void execute(Renderer *renderer, GraphicsContext *ctx) Q_DECL_OVERRIDE;
-
-private:
- Shader *m_shader = nullptr;
-};
-} // Render
-
-} // Qt3DRender
-
-QT_END_NAMESPACE
-
-#endif // QT3DRENDER_RENDER_GLCOMMANDS_P_H
diff --git a/src/render/backend/openglvertexarrayobject.cpp b/src/render/backend/openglvertexarrayobject.cpp
deleted file mode 100644
index 0c4fd8c9d..000000000
--- a/src/render/backend/openglvertexarrayobject.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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$
-**
-****************************************************************************/
-
-#include "openglvertexarrayobject_p.h"
-#include <Qt3DRender/private/submissioncontext_p.h>
-#include <Qt3DRender/private/renderer_p.h>
-#include <Qt3DRender/private/nodemanagers_p.h>
-#include <Qt3DRender/private/managers_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-namespace Render {
-
-OpenGLVertexArrayObject::OpenGLVertexArrayObject()
- : m_ctx(nullptr)
- , m_specified(false)
- , m_supportsVao(false)
-{}
-
-void OpenGLVertexArrayObject::bind()
-{
- Q_ASSERT(m_ctx);
- if (m_supportsVao) {
- Q_ASSERT(!m_vao.isNull());
- Q_ASSERT(m_vao->isCreated());
- m_vao->bind();
- } else {
- // Unbind any other VAO that may have been bound and not released correctly
- if (m_ctx->m_currentVAO != nullptr && m_ctx->m_currentVAO != this)
- m_ctx->m_currentVAO->release();
-
- m_ctx->m_currentVAO = this;
- // We need to specify array and vertex attributes
- for (const SubmissionContext::VAOVertexAttribute &attr : qAsConst(m_vertexAttributes))
- m_ctx->enableAttribute(attr);
- if (!m_indexAttribute.isNull())
- m_ctx->bindGLBuffer(m_ctx->m_renderer->nodeManagers()->glBufferManager()->data(m_indexAttribute),
- GLBuffer::IndexBuffer);
- }
-}
-
-void OpenGLVertexArrayObject::release()
-{
- Q_ASSERT(m_ctx);
- if (m_supportsVao) {
- Q_ASSERT(!m_vao.isNull());
- Q_ASSERT(m_vao->isCreated());
- m_vao->release();
- } else {
- if (m_ctx->m_currentVAO == this) {
- for (const SubmissionContext::VAOVertexAttribute &attr : qAsConst(m_vertexAttributes))
- m_ctx->disableAttribute(attr);
- m_ctx->m_currentVAO = nullptr;
- }
- }
-}
-
-// called from Render thread
-void OpenGLVertexArrayObject::create(SubmissionContext *ctx, const VAOIdentifier &key)
-{
- QMutexLocker lock(&m_mutex);
-
- Q_ASSERT(!m_ctx && !m_vao);
-
- m_ctx = ctx;
- m_supportsVao = m_ctx->supportsVAO();
- if (m_supportsVao) {
- m_vao.reset(new QOpenGLVertexArrayObject());
- m_vao->create();
- }
- m_owners = key;
-}
-
-// called from Render thread
-void OpenGLVertexArrayObject::destroy()
-{
- QMutexLocker locker(&m_mutex);
-
- Q_ASSERT(m_ctx);
- cleanup();
-}
-
-void OpenGLVertexArrayObject::cleanup()
-{
- m_vao.reset();
- m_ctx = nullptr;
- m_specified = false;
- m_supportsVao = false;
- m_indexAttribute = SubmissionContext::VAOIndexAttribute();
- m_vertexAttributes.clear();
-}
-
-// called from job
-bool OpenGLVertexArrayObject::isAbandoned(GeometryManager *geomMgr, ShaderManager *shaderMgr)
-{
- QMutexLocker lock(&m_mutex);
-
- if (!m_ctx)
- return false;
-
- const bool geometryExists = (geomMgr->data(m_owners.first) != nullptr);
- const bool shaderExists = (shaderMgr->data(m_owners.second) != nullptr);
-
- return !geometryExists || !shaderExists;
-}
-
-void OpenGLVertexArrayObject::saveVertexAttribute(const SubmissionContext::VAOVertexAttribute &attr)
-{
- // Remove any vertexAttribute already at location
- for (auto i = m_vertexAttributes.size() - 1; i >= 0; --i) {
- if (m_vertexAttributes.at(i).location == attr.location) {
- m_vertexAttributes.removeAt(i);
- break;
- }
- }
- m_vertexAttributes.push_back(attr);
-}
-
-
-} // namespace Render
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
diff --git a/src/render/backend/openglvertexarrayobject_p.h b/src/render/backend/openglvertexarrayobject_p.h
deleted file mode 100644
index eee837221..000000000
--- a/src/render/backend/openglvertexarrayobject_p.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 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 OPENGLVERTEXARRAYOBJECT_H
-#define OPENGLVERTEXARRAYOBJECT_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 <QtGui/qopenglvertexarrayobject.h>
-#include <Qt3DRender/private/submissioncontext_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-namespace Render {
-
-class GeometryManager;
-class ShaderManager;
-
-typedef QPair<HGeometry, HShader> VAOIdentifier;
-
-class OpenGLVertexArrayObject
-{
-public:
- OpenGLVertexArrayObject();
-
- void bind();
- void release();
-
- void create(SubmissionContext *ctx, const VAOIdentifier &key);
- void destroy();
- void cleanup();
-
- bool isAbandoned(GeometryManager *geomMgr, ShaderManager *shaderMgr);
-
- QOpenGLVertexArrayObject *vao() { return m_vao.data(); }
- const QOpenGLVertexArrayObject *vao() const { return m_vao.data(); }
-
- void setSpecified(bool b) { m_specified = b; }
- bool isSpecified() const { return m_specified; }
-
-
-private:
- QMutex m_mutex;
- SubmissionContext *m_ctx;
- QScopedPointer<QOpenGLVertexArrayObject> m_vao;
- bool m_specified;
- bool m_supportsVao;
- VAOIdentifier m_owners;
-
- friend class SubmissionContext;
-
- void saveVertexAttribute(const SubmissionContext::VAOVertexAttribute &attr);
- inline void saveIndexAttribute(HGLBuffer glBufferHandle) { m_indexAttribute = glBufferHandle; }
-
- QVector<SubmissionContext::VAOVertexAttribute> m_vertexAttributes;
- SubmissionContext::VAOIndexAttribute m_indexAttribute;
-};
-
-} // namespace Render
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
-
-#endif // OPENGLVERTEXARRAYOBJECT_H
diff --git a/src/render/backend/render-backend.pri b/src/render/backend/render-backend.pri
index cde9e77b9..352de3be5 100644
--- a/src/render/backend/render-backend.pri
+++ b/src/render/backend/render-backend.pri
@@ -2,15 +2,9 @@ INCLUDEPATH += $$PWD
HEADERS += \
$$PWD/renderthread_p.h \
- $$PWD/renderconfiguration_p.h \
- $$PWD/renderer_p.h \
- $$PWD/renderview_p.h \
- $$PWD/rendercommand_p.h \
- $$PWD/renderqueue_p.h \
$$PWD/parameterpack_p.h \
$$PWD/rendertarget_p.h \
$$PWD/attachmentpack_p.h \
- $$PWD/shadervariables_p.h \
$$PWD/qgraphicsutils_p.h \
$$PWD/managers_p.h \
$$PWD/handle_types_p.h \
@@ -24,7 +18,6 @@ HEADERS += \
$$PWD/boundingvolumedebug_p.h \
$$PWD/nodemanagers_p.h \
$$PWD/triangleboundingvolume_p.h \
- $$PWD/openglvertexarrayobject_p.h \
$$PWD/trianglesextractor_p.h \
$$PWD/buffervisitor_p.h \
$$PWD/bufferutils_p.h \
@@ -36,25 +29,15 @@ HEADERS += \
$$PWD/backendnode_p.h \
$$PWD/rendertargetoutput_p.h \
$$PWD/uniform_p.h \
- $$PWD/shaderparameterpack_p.h \
- $$PWD/renderviewbuilder_p.h \
$$PWD/frameprofiler_p.h \
$$PWD/offscreensurfacehelper_p.h \
$$PWD/resourceaccessor_p.h \
- $$PWD/commandthread_p.h \
$$PWD/visitorutils_p.h \
$$PWD/segmentsvisitor_p.h \
- $$PWD/pointsvisitor_p.h \
- $$PWD/renderercache_p.h \
- $$PWD/glcommands_p.h
+ $$PWD/pointsvisitor_p.h
SOURCES += \
$$PWD/renderthread.cpp \
- $$PWD/renderconfiguration.cpp \
- $$PWD/renderer.cpp \
- $$PWD/renderview.cpp \
- $$PWD/rendercommand.cpp \
- $$PWD/renderqueue.cpp \
$$PWD/parameterpack.cpp \
$$PWD/rendertarget.cpp \
$$PWD/managers.cpp \
@@ -75,16 +58,11 @@ SOURCES += \
$$PWD/backendnode.cpp \
$$PWD/rendertargetoutput.cpp \
$$PWD/attachmentpack.cpp \
- $$PWD/openglvertexarrayobject.cpp \
$$PWD/uniform.cpp \
- $$PWD/shaderparameterpack.cpp \
- $$PWD/renderviewbuilder.cpp \
$$PWD/offscreensurfacehelper.cpp \
$$PWD/resourceaccessor.cpp \
$$PWD/segmentsvisitor.cpp \
- $$PWD/commandthread.cpp \
- $$PWD/pointsvisitor.cpp \
- $$PWD/glcommands.cpp
+ $$PWD/pointsvisitor.cpp
include($$QT3D_BUILD_ROOT/src/core/qt3dcore-config.pri)
QT_FOR_CONFIG += 3dcore-private
diff --git a/src/render/backend/rendercommand.cpp b/src/render/backend/rendercommand.cpp
deleted file mode 100644
index e60b17668..000000000
--- a/src/render/backend/rendercommand.cpp
+++ /dev/null
@@ -1,76 +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$
-**
-****************************************************************************/
-
-#include "rendercommand_p.h"
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-namespace Render {
-
-RenderCommand::RenderCommand()
- : m_stateSet(nullptr)
- , m_depth(0.0f)
- , m_changeCost(0)
- , m_type(RenderCommand::Draw)
- , m_primitiveCount(0)
- , m_primitiveType(QGeometryRenderer::Triangles)
- , m_restartIndexValue(-1)
- , m_firstInstance(0)
- , m_firstVertex(0)
- , m_verticesPerPatch(0)
- , m_instanceCount(0)
- , m_indexOffset(0)
- , m_indexAttributeByteOffset(0)
- , m_indexAttributeDataType(GL_UNSIGNED_SHORT)
- , m_indirectAttributeByteOffset(0)
- , m_drawIndexed(false)
- , m_drawIndirect(false)
- , m_primitiveRestartEnabled(false)
- , m_isValid(false)
-{
- m_workGroups[0] = 0;
- m_workGroups[1] = 0;
- m_workGroups[2] = 0;
-}
-
-} // namespace Render
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
diff --git a/src/render/backend/rendercommand_p.h b/src/render/backend/rendercommand_p.h
deleted file mode 100644
index 67e02d35b..000000000
--- a/src/render/backend/rendercommand_p.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
-** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
-** 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 QT3DRENDER_RENDER_RENDERCOMMAND_H
-#define QT3DRENDER_RENDER_RENDERCOMMAND_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 <qglobal.h>
-#include <Qt3DRender/private/shaderparameterpack_p.h>
-#include <Qt3DRender/private/handle_types_p.h>
-#include <Qt3DRender/qgeometryrenderer.h>
-#include <QOpenGLShaderProgram>
-#include <QOpenGLTexture>
-#include <QMatrix4x4>
-
-QT_BEGIN_NAMESPACE
-
-class QOpenGLVertexArrayObject;
-
-namespace Qt3DRender {
-
-namespace Render {
-
-class RenderStateSet;
-
-class Q_AUTOTEST_EXPORT RenderCommand
-{
-public:
- RenderCommand();
-
- HVao m_vao; // VAO used during the submission step to store all states and VBOs
- HShader m_shader; // Shader for given pass and mesh
- HMaterial m_material; // Purely used to ease sorting (minimize stage changes, binding changes ....)
- ShaderParameterPack m_parameterPack; // Might need to be reworked so as to be able to destroy the
- // Texture while submission is happening.
- RenderStateSet *m_stateSet;
-
- HGeometry m_geometry;
- HGeometryRenderer m_geometryRenderer;
-
- HBuffer m_indirectDrawBuffer; // Reference to indirect draw buffer (valid only m_drawIndirect == true)
-
- // A QAttribute pack might be interesting
- // This is a temporary fix in the meantime, to remove the hacked methods in Technique
- QVector<int> m_attributes;
-
- float m_depth;
- int m_changeCost;
- uint m_shaderDna;
-
- enum CommandType {
- Draw,
- Compute
- };
-
- CommandType m_type;
- int m_workGroups[3];
-
- // Values filled for draw calls
- GLsizei m_primitiveCount;
- QGeometryRenderer::PrimitiveType m_primitiveType;
- int m_restartIndexValue;
- int m_firstInstance;
- int m_firstVertex;
- int m_verticesPerPatch;
- int m_instanceCount;
- int m_indexOffset;
- uint m_indexAttributeByteOffset;
- GLint m_indexAttributeDataType;
- uint m_indirectAttributeByteOffset;
- bool m_drawIndexed;
- bool m_drawIndirect;
- bool m_primitiveRestartEnabled;
- bool m_isValid;
-};
-
-} // namespace Render
-
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
-
-#endif // QT3DRENDER_RENDER_RENDERCOMMAND_H
diff --git a/src/render/backend/renderconfiguration.cpp b/src/render/backend/renderconfiguration.cpp
deleted file mode 100644
index 730676996..000000000
--- a/src/render/backend/renderconfiguration.cpp
+++ /dev/null
@@ -1,54 +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$
-**
-****************************************************************************/
-
-#include "renderconfiguration_p.h"
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-namespace Render {
-
-RenderConfiguration::RenderConfiguration()
-{
-}
-
-} // namespace Render
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
diff --git a/src/render/backend/renderconfiguration_p.h b/src/render/backend/renderconfiguration_p.h
deleted file mode 100644
index 9aa950faa..000000000
--- a/src/render/backend/renderconfiguration_p.h
+++ /dev/null
@@ -1,72 +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 QT3DRENDER_RENDER_RENDERCONFIGURATION_H
-#define QT3DRENDER_RENDER_RENDERCONFIGURATION_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 <qglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-namespace Render {
-
-class RenderConfiguration
-{
-public:
- RenderConfiguration();
-};
-
-} // namespace Render
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
-
-#endif // QT3DRENDER_RENDER_RENDERCONFIGURATION_H
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
deleted file mode 100644
index 2611fb6cc..000000000
--- a/src/render/backend/renderer.cpp
+++ /dev/null
@@ -1,2067 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
-** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
-** 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 "renderer_p.h"
-
-#include <Qt3DCore/qentity.h>
-
-#include <Qt3DRender/qmaterial.h>
-#include <Qt3DRender/qmesh.h>
-#include <Qt3DRender/qrenderpass.h>
-#include <Qt3DRender/qshaderprogram.h>
-#include <Qt3DRender/qtechnique.h>
-#include <Qt3DRender/qrenderaspect.h>
-#include <Qt3DRender/qeffect.h>
-
-#include <Qt3DRender/private/qsceneimporter_p.h>
-#include <Qt3DRender/private/renderstates_p.h>
-#include <Qt3DRender/private/cameraselectornode_p.h>
-#include <Qt3DRender/private/framegraphvisitor_p.h>
-#include <Qt3DRender/private/graphicscontext_p.h>
-#include <Qt3DRender/private/cameralens_p.h>
-#include <Qt3DRender/private/rendercommand_p.h>
-#include <Qt3DRender/private/entity_p.h>
-#include <Qt3DRender/private/renderlogging_p.h>
-#include <Qt3DRender/private/material_p.h>
-#include <Qt3DRender/private/renderpassfilternode_p.h>
-#include <Qt3DRender/private/renderqueue_p.h>
-#include <Qt3DRender/private/shader_p.h>
-#include <Qt3DRender/private/buffer_p.h>
-#include <Qt3DRender/private/glbuffer_p.h>
-#include <Qt3DRender/private/renderstateset_p.h>
-#include <Qt3DRender/private/technique_p.h>
-#include <Qt3DRender/private/renderthread_p.h>
-#include <Qt3DRender/private/renderview_p.h>
-#include <Qt3DRender/private/scenemanager_p.h>
-#include <Qt3DRender/private/techniquefilternode_p.h>
-#include <Qt3DRender/private/viewportnode_p.h>
-#include <Qt3DRender/private/vsyncframeadvanceservice_p.h>
-#include <Qt3DRender/private/pickeventfilter_p.h>
-#include <Qt3DRender/private/managers_p.h>
-#include <Qt3DRender/private/buffermanager_p.h>
-#include <Qt3DRender/private/nodemanagers_p.h>
-#include <Qt3DRender/private/gltexturemanager_p.h>
-#include <Qt3DRender/private/gltexture_p.h>
-#include <Qt3DRender/private/geometryrenderermanager_p.h>
-#include <Qt3DRender/private/techniquemanager_p.h>
-#include <Qt3DRender/private/openglvertexarrayobject_p.h>
-#include <Qt3DRender/private/platformsurfacefilter_p.h>
-#include <Qt3DRender/private/loadbufferjob_p.h>
-#include <Qt3DRender/private/rendercapture_p.h>
-#include <Qt3DRender/private/updatelevelofdetailjob_p.h>
-#include <Qt3DRender/private/buffercapture_p.h>
-#include <Qt3DRender/private/offscreensurfacehelper_p.h>
-#include <Qt3DRender/private/renderviewbuilder_p.h>
-#include <Qt3DRender/private/commandthread_p.h>
-#include <Qt3DRender/private/glcommands_p.h>
-
-#include <Qt3DRender/qcameralens.h>
-#include <Qt3DCore/private/qeventfilterservice_p.h>
-#include <Qt3DCore/private/qabstractaspectjobmanager_p.h>
-#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
-
-#if QT_CONFIG(qt3d_profile_jobs)
-#include <Qt3DCore/private/aspectcommanddebugger_p.h>
-#endif
-
-#include <QStack>
-#include <QOffscreenSurface>
-#include <QSurface>
-#include <QElapsedTimer>
-#include <QLibraryInfo>
-#include <QPluginLoader>
-#include <QDir>
-#include <QUrl>
-#include <QOffscreenSurface>
-#include <QWindow>
-
-#include <QtGui/private/qopenglcontext_p.h>
-
-// For Debug purposes only
-#include <QThread>
-
-
-#if QT_CONFIG(qt3d_profile_jobs)
-#include <Qt3DCore/private/qthreadpooler_p.h>
-#include <Qt3DRender/private/job_common_p.h>
-#include <Qt3DRender/private/commandexecuter_p.h>
-#endif
-
-#include <Qt3DRender/private/frameprofiler_p.h>
-
-QT_BEGIN_NAMESPACE
-
-using namespace Qt3DCore;
-
-namespace Qt3DRender {
-namespace Render {
-/*!
- \internal
-
- Renderer shutdown procedure:
-
- Since the renderer relies on the surface and OpenGLContext to perform its cleanup,
- it is shutdown when the surface is set to nullptr
-
- When the surface is set to nullptr this will request the RenderThread to terminate
- and will prevent createRenderBinJobs from returning a set of jobs as there is nothing
- more to be rendered.
-
- In turn, this will call shutdown which will make the OpenGL context current one last time
- to allow cleanups requiring a call to QOpenGLContext::currentContext to execute properly.
- At the end of that function, the GraphicsContext is set to null.
-
- At this point though, the QAspectThread is still running its event loop and will only stop
- a short while after.
- */
-
-Renderer::Renderer(QRenderAspect::RenderType type)
- : m_services(nullptr)
- , m_nodesManager(nullptr)
- , m_renderSceneRoot(nullptr)
- , m_defaultRenderStateSet(nullptr)
- , m_submissionContext(nullptr)
- , m_renderQueue(new RenderQueue())
- , m_renderThread(type == QRenderAspect::Threaded ? new RenderThread(this) : nullptr)
- , m_commandThread(new CommandThread(this))
- , m_vsyncFrameAdvanceService(new VSyncFrameAdvanceService(m_renderThread != nullptr))
- , m_waitForInitializationToBeCompleted(0)
- , m_pickEventFilter(new PickEventFilter())
- , m_exposed(0)
- , m_lastFrameCorrect(0)
- , m_glContext(nullptr)
- , m_shareContext(nullptr)
- , m_shaderCache(new ShaderCache())
- , m_pickBoundingVolumeJob(PickBoundingVolumeJobPtr::create())
- , m_rayCastingJob(RayCastingJobPtr::create())
- , m_time(0)
- , m_settings(nullptr)
- , m_updateShaderDataTransformJob(Render::UpdateShaderDataTransformJobPtr::create())
- , m_cleanupJob(Render::FrameCleanupJobPtr::create())
- , m_worldTransformJob(Render::UpdateWorldTransformJobPtr::create())
- , m_expandBoundingVolumeJob(Render::ExpandBoundingVolumeJobPtr::create())
- , m_calculateBoundingVolumeJob(Render::CalculateBoundingVolumeJobPtr::create())
- , m_updateWorldBoundingVolumeJob(Render::UpdateWorldBoundingVolumeJobPtr::create())
- , m_updateTreeEnabledJob(Render::UpdateTreeEnabledJobPtr::create())
- , m_sendRenderCaptureJob(Render::SendRenderCaptureJobPtr::create(this))
- , m_sendBufferCaptureJob(Render::SendBufferCaptureJobPtr::create())
- , m_updateSkinningPaletteJob(Render::UpdateSkinningPaletteJobPtr::create())
- , m_updateLevelOfDetailJob(Render::UpdateLevelOfDetailJobPtr::create())
- , m_updateMeshTriangleListJob(Render::UpdateMeshTriangleListJobPtr::create())
- , m_filterCompatibleTechniqueJob(Render::FilterCompatibleTechniqueJobPtr::create())
- , m_bufferGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForDirtyBuffers(); }, JobTypes::DirtyBufferGathering))
- , m_vaoGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForAbandonedVaos(); }, JobTypes::DirtyVaoGathering))
- , m_textureGathererJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { lookForDirtyTextures(); }, JobTypes::DirtyTextureGathering))
- , m_introspectShaderJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([this] { reloadDirtyShaders(); }, JobTypes::DirtyShaderGathering))
- , m_syncTextureLoadingJob(Render::GenericLambdaJobPtr<std::function<void ()>>::create([] {}, JobTypes::SyncTextureLoading))
- , m_ownedContext(false)
- , m_offscreenHelper(nullptr)
- #if QT_CONFIG(qt3d_profile_jobs)
- , m_commandExecuter(new Qt3DRender::Debug::CommandExecuter(this))
- #endif
-{
- // Set renderer as running - it will wait in the context of the
- // RenderThread for RenderViews to be submitted
- m_running.fetchAndStoreOrdered(1);
- if (m_renderThread)
- m_renderThread->waitForStart();
-
- // Create jobs to update transforms and bounding volumes
- // We can only update bounding volumes once all world transforms are known
- m_updateWorldBoundingVolumeJob->addDependency(m_worldTransformJob);
- m_updateWorldBoundingVolumeJob->addDependency(m_calculateBoundingVolumeJob);
- m_expandBoundingVolumeJob->addDependency(m_updateWorldBoundingVolumeJob);
- m_updateShaderDataTransformJob->addDependency(m_worldTransformJob);
- m_pickBoundingVolumeJob->addDependency(m_expandBoundingVolumeJob);
- // m_calculateBoundingVolumeJob's dependency on m_updateTreeEnabledJob is set in renderBinJobs
-
- // Dirty texture gathering depends on m_syncTextureLoadingJob
- // m_syncTextureLoadingJob will depend on the texture loading jobs
- m_textureGathererJob->addDependency(m_syncTextureLoadingJob);
-
- // Ensures all skeletons are loaded before we try to update them
- m_updateSkinningPaletteJob->addDependency(m_syncTextureLoadingJob);
-
- // All world stuff depends on the RenderEntity's localBoundingVolume
- m_updateLevelOfDetailJob->addDependency(m_updateMeshTriangleListJob);
- m_pickBoundingVolumeJob->addDependency(m_updateMeshTriangleListJob);
- m_rayCastingJob->addDependency(m_updateMeshTriangleListJob);
-
- m_introspectShaderJob->addDependency(m_filterCompatibleTechniqueJob);
-
- m_filterCompatibleTechniqueJob->setRenderer(this);
-
- m_defaultRenderStateSet = new RenderStateSet;
- m_defaultRenderStateSet->addState(RenderStateSet::createState<DepthTest>(GL_LESS));
- m_defaultRenderStateSet->addState(RenderStateSet::createState<CullFace>(GL_BACK));
- m_defaultRenderStateSet->addState(RenderStateSet::createState<ColorMask>(true, true, true, true));
-}
-
-Renderer::~Renderer()
-{
- // If using a threaded rendering approach, tell the thread to exit
- // and wait for it to be done
- m_running.fetchAndStoreOrdered(0);
- if (m_renderThread)
- m_renderThread->wait();
-
- delete m_renderQueue;
- delete m_defaultRenderStateSet;
- delete m_shaderCache;
-
- if (!m_ownedContext)
- QObject::disconnect(m_contextConnection);
-}
-
-void Renderer::dumpInfo() const
-{
- qDebug() << Q_FUNC_INFO << "t =" << m_time;
-
- const ShaderManager *shaderManager = m_nodesManager->shaderManager();
- qDebug() << "=== Shader Manager ===";
- qDebug() << *shaderManager;
-
- const TextureManager *textureManager = m_nodesManager->textureManager();
- qDebug() << "=== Texture Manager ===";
- qDebug() << *textureManager;
-
- const TextureImageManager *textureImageManager = m_nodesManager->textureImageManager();
- qDebug() << "=== Texture Image Manager ===";
- qDebug() << *textureImageManager;
-}
-
-qint64 Renderer::time() const
-{
- return m_time;
-}
-
-void Renderer::setTime(qint64 time)
-{
- m_time = time;
-}
-
-void Renderer::setNodeManagers(NodeManagers *managers)
-{
- m_nodesManager = managers;
-
- m_updateShaderDataTransformJob->setManagers(m_nodesManager);
- m_cleanupJob->setManagers(m_nodesManager);
- m_calculateBoundingVolumeJob->setManagers(m_nodesManager);
- m_pickBoundingVolumeJob->setManagers(m_nodesManager);
- m_rayCastingJob->setManagers(m_nodesManager);
- m_updateWorldBoundingVolumeJob->setManager(m_nodesManager->renderNodesManager());
- m_sendRenderCaptureJob->setManagers(m_nodesManager);
- m_sendBufferCaptureJob->setManagers(m_nodesManager);
- m_updateLevelOfDetailJob->setManagers(m_nodesManager);
- m_updateSkinningPaletteJob->setManagers(m_nodesManager);
- m_updateMeshTriangleListJob->setManagers(m_nodesManager);
- m_filterCompatibleTechniqueJob->setManager(m_nodesManager->techniqueManager());
-}
-
-void Renderer::setServices(QServiceLocator *services)
-{
- m_services = services;
-
- m_nodesManager->sceneManager()->setDownloadService(m_services->downloadHelperService());
-}
-
-NodeManagers *Renderer::nodeManagers() const
-{
- return m_nodesManager;
-}
-
-/*!
- \internal
-
- Return context which can be used to share resources safely
- with qt3d main render context.
-*/
-QOpenGLContext *Renderer::shareContext() const
-{
- QMutexLocker lock(&m_shareContextMutex);
- return m_shareContext ? m_shareContext
- : (m_submissionContext->openGLContext()
- ? m_submissionContext->openGLContext()->shareContext()
- : nullptr);
-}
-
-// Executed in the command thread
-void Renderer::loadShader(Shader *shader) const
-{
- Profiling::GLTimeRecorder recorder(Profiling::ShaderUpload);
- LoadShaderCommand cmd(shader);
- m_commandThread->executeCommand(&cmd);
-}
-
-void Renderer::setOpenGLContext(QOpenGLContext *context)
-{
- m_glContext = context;
-}
-
-// Called in RenderThread context by the run method of RenderThread
-// RenderThread has locked the mutex already and unlocks it when this
-// method termintates
-void Renderer::initialize()
-{
- m_submissionContext.reset(new SubmissionContext);
- m_submissionContext->setRenderer(this);
-
- QOpenGLContext* ctx = m_glContext;
-
- {
- QMutexLocker lock(&m_shareContextMutex);
- // If we are using our own context (not provided by QtQuick),
- // we need to create it
- if (!m_glContext) {
- ctx = new QOpenGLContext;
- ctx->setShareContext(qt_gl_global_share_context());
-
- // TO DO: Shouldn't we use the highest context available and trust
- // QOpenGLContext to fall back on the best lowest supported ?
- const QByteArray debugLoggingMode = qgetenv("QT3DRENDER_DEBUG_LOGGING");
-
- if (!debugLoggingMode.isEmpty()) {
- QSurfaceFormat sf = ctx->format();
- sf.setOption(QSurfaceFormat::DebugContext);
- ctx->setFormat(sf);
- }
-
- // Create OpenGL context
- if (ctx->create())
- qCDebug(Backend) << "OpenGL context created with actual format" << ctx->format();
- else
- qCWarning(Backend) << Q_FUNC_INFO << "OpenGL context creation failed";
- m_ownedContext = true;
- } else {
- // Context is not owned by us, so we need to know if it gets destroyed
- m_contextConnection = QObject::connect(m_glContext, &QOpenGLContext::aboutToBeDestroyed,
- [this] { releaseGraphicsResources(); });
- }
-
- if (!ctx->shareContext()) {
- m_shareContext = new QOpenGLContext;
- m_shareContext->setFormat(ctx->format());
- m_shareContext->setShareContext(ctx);
- m_shareContext->create();
- }
-
- // Set shader cache on submission context and command thread
- m_submissionContext->setShaderCache(m_shaderCache);
- m_commandThread->setShaderCache(m_shaderCache);
-
- // Note: we don't have a surface at this point
- // The context will be made current later on (at render time)
- m_submissionContext->setOpenGLContext(ctx);
-
- // Store the format used by the context and queue up creating an
- // offscreen surface in the main thread so that it is available
- // for use when we want to shutdown the renderer. We need to create
- // the offscreen surface on the main thread because on some platforms
- // (MS Windows), an offscreen surface is just a hidden QWindow.
- m_format = ctx->format();
- QMetaObject::invokeMethod(m_offscreenHelper, "createOffscreenSurface");
-
- // Initialize command thread (uses the offscreen surface to make its own ctx current)
- m_commandThread->initialize(ctx, m_offscreenHelper);
- // Note: the offscreen surface is also used at shutdown time to release resources
- // of the submission gl context (when the window is already gone).
- // By that time (in releaseGraphicResources), the commandThread has been destroyed
- // and the offscreenSurface can be reused
- }
-
- // Awake setScenegraphRoot in case it was waiting
- m_waitForInitializationToBeCompleted.release(1);
- // Allow the aspect manager to proceed
- m_vsyncFrameAdvanceService->proceedToNextFrame();
-}
-
-/*!
- * \internal
- *
- * Signals for the renderer to stop rendering. If a threaded renderer is in use,
- * the render thread will call releaseGraphicsResources() just before the thread exits.
- * If rendering synchronously, this function will call releaseGraphicsResources().
- */
-void Renderer::shutdown()
-{
- qCDebug(Backend) << Q_FUNC_INFO << "Requesting renderer shutdown";
- m_running.store(0);
-
- // We delete any renderqueue that we may not have had time to render
- // before the surface was destroyed
- qDeleteAll(m_renderQueue->nextFrameQueue());
- m_renderQueue->reset();
-
- m_commandThread->shutdown();
-
- if (!m_renderThread) {
- releaseGraphicsResources();
- } else {
- // Wake up the render thread in case it is waiting for some renderviews
- // to be ready. The isReadyToSubmit() function checks for a shutdown
- // having been requested.
- m_submitRenderViewsSemaphore.release(1);
- m_renderThread->wait();
- }
-}
-
-/*!
- \internal
-
- When using a threaded renderer this function is called in the context of the
- RenderThread to do any shutdown and cleanup that needs to be performed in the
- thread where the OpenGL context lives.
-
- When using Scene3D or anything that provides a custom QOpenGLContext (not
- owned by Qt3D) this function is called whenever the signal
- QOpenGLContext::aboutToBeDestroyed is emitted. In that case this function
- is called in the context of the emitter's thread.
-*/
-void Renderer::releaseGraphicsResources()
-{
- // We may get called twice when running inside of a Scene3D. Once when Qt Quick
- // wants to shutdown, and again when the render aspect gets unregistered. So
- // check that we haven't already cleaned up before going any further.
- if (!m_submissionContext)
- return;
-
- // Try to temporarily make the context current so we can free up any resources
- QMutexLocker locker(&m_offscreenSurfaceMutex);
- QOffscreenSurface *offscreenSurface = m_offscreenHelper->offscreenSurface();
- if (!offscreenSurface) {
- qWarning() << "Failed to make context current: OpenGL resources will not be destroyed";
- return;
- }
-
- QOpenGLContext *context = m_submissionContext->openGLContext();
- Q_ASSERT(context);
- if (context->makeCurrent(offscreenSurface)) {
-
- // Clean up the graphics context and any resources
- const QVector<GLTexture*> activeTextures = m_nodesManager->glTextureManager()->activeResources();
- for (GLTexture *tex : activeTextures)
- tex->destroyGLTexture();
-
- // Do the same thing with buffers
- const QVector<HGLBuffer> activeBuffers = m_nodesManager->glBufferManager()->activeHandles();
- for (const HGLBuffer &bufferHandle : activeBuffers) {
- GLBuffer *buffer = m_nodesManager->glBufferManager()->data(bufferHandle);
- buffer->destroy(m_submissionContext.data());
- }
-
- // Do the same thing with VAOs
- const QVector<HVao> activeVaos = m_nodesManager->vaoManager()->activeHandles();
- for (const HVao &vaoHandle : activeVaos) {
- OpenGLVertexArrayObject *vao = m_nodesManager->vaoManager()->data(vaoHandle);
- vao->destroy();
- }
-
- context->doneCurrent();
- } else {
- qWarning() << "Failed to make context current: OpenGL resources will not be destroyed";
- }
-
- if (m_ownedContext)
- delete context;
- if (m_shareContext)
- delete m_shareContext;
-
- m_submissionContext.reset(nullptr);
- qCDebug(Backend) << Q_FUNC_INFO << "Renderer properly shutdown";
-}
-
-void Renderer::setSurfaceExposed(bool exposed)
-{
- qCDebug(Backend) << "Window exposed: " << exposed;
- m_exposed.fetchAndStoreOrdered(exposed);
-}
-
-Render::FrameGraphNode *Renderer::frameGraphRoot() const
-{
- Q_ASSERT(m_settings);
- if (m_nodesManager && m_nodesManager->frameGraphManager() && m_settings)
- return m_nodesManager->frameGraphManager()->lookupNode(m_settings->activeFrameGraphID());
- return nullptr;
-}
-
-// QAspectThread context
-// Order of execution :
-// 1) RenderThread is created -> release 1 of m_waitForInitializationToBeCompleted when started
-// 2) setSceneRoot waits to acquire initialization
-// 3) submitRenderView -> check for surface
-// -> make surface current + create proper glHelper if needed
-void Renderer::setSceneRoot(QBackendNodeFactory *factory, Entity *sgRoot)
-{
- Q_ASSERT(sgRoot);
- Q_UNUSED(factory);
-
- // If initialization hasn't been completed we must wait
- m_waitForInitializationToBeCompleted.acquire();
-
- m_renderSceneRoot = sgRoot;
- if (!m_renderSceneRoot)
- qCWarning(Backend) << "Failed to build render scene";
- m_renderSceneRoot->dump();
- qCDebug(Backend) << Q_FUNC_INFO << "DUMPING SCENE";
-
- // Set the scene root on the jobs
- m_worldTransformJob->setRoot(m_renderSceneRoot);
- m_expandBoundingVolumeJob->setRoot(m_renderSceneRoot);
- m_calculateBoundingVolumeJob->setRoot(m_renderSceneRoot);
- m_cleanupJob->setRoot(m_renderSceneRoot);
- m_pickBoundingVolumeJob->setRoot(m_renderSceneRoot);
- m_rayCastingJob->setRoot(m_renderSceneRoot);
- m_updateLevelOfDetailJob->setRoot(m_renderSceneRoot);
- m_updateSkinningPaletteJob->setRoot(m_renderSceneRoot);
- m_updateTreeEnabledJob->setRoot(m_renderSceneRoot);
-
- // Set all flags to dirty
- m_dirtyBits.marked |= AbstractRenderer::AllDirty;
-}
-
-void Renderer::registerEventFilter(QEventFilterService *service)
-{
- qCDebug(Backend) << Q_FUNC_INFO << QThread::currentThread();
- service->registerEventFilter(m_pickEventFilter.data(), 1024);
-}
-
-void Renderer::setSettings(RenderSettings *settings)
-{
- m_settings = settings;
-}
-
-RenderSettings *Renderer::settings() const
-{
- return m_settings;
-}
-
-void Renderer::render()
-{
- // Traversing the framegraph tree from root to lead node
- // Allows us to define the rendering set up
- // Camera, RenderTarget ...
-
- // Utimately the renderer should be a framework
- // For the processing of the list of renderviews
-
- // Matrice update, bounding volumes computation ...
- // Should be jobs
-
- // namespace Qt3DCore has 2 distincts node trees
- // One scene description
- // One framegraph description
-
- while (m_running.load() > 0) {
- doRender();
- // TO DO: Restore windows exposed detection
- // Probably needs to happens some place else though
- }
-}
-
-void Renderer::doRender(bool scene3dBlocking)
-{
- Renderer::ViewSubmissionResultData submissionData;
- bool hasCleanedQueueAndProceeded = false;
- bool preprocessingComplete = false;
- bool beganDrawing = false;
- const bool canSubmit = isReadyToSubmit();
-
- // Lock the mutex to protect access to the renderQueue while we look for its state
- QMutexLocker locker(m_renderQueue->mutex());
- bool queueIsComplete = m_renderQueue->isFrameQueueComplete();
- const bool queueIsEmpty = m_renderQueue->targetRenderViewCount() == 0;
-
- // Scene3D Blocking Mode
- if (scene3dBlocking && !queueIsComplete && !queueIsEmpty) {
- int i = 0;
- // We wait at most 10ms to avoid a case we could never recover from
- while (!queueIsComplete && i++ < 10) {
- QThread::msleep(1);
- qCDebug(Backend) << Q_FUNC_INFO << "Waiting for ready queue (try:" << i << "/ 10)";
- locker.unlock();
- queueIsComplete = m_renderQueue->isFrameQueueComplete();
- locker.relock();
- }
- }
-
- // When using synchronous rendering (QtQuick)
- // We are not sure that the frame queue is actually complete
- // Since a call to render may not be synched with the completions
- // of the RenderViewJobs
- // In such a case we return early, waiting for a next call with
- // the frame queue complete at this point
-
- // RenderQueue is complete (but that means it may be of size 0)
- if (canSubmit && (queueIsComplete && !queueIsEmpty)) {
- const QVector<Render::RenderView *> renderViews = m_renderQueue->nextFrameQueue();
-
-#if QT_CONFIG(qt3d_profile_jobs)
- // Save start of frame
- JobRunStats submissionStatsPart1;
- JobRunStats submissionStatsPart2;
- submissionStatsPart1.jobId.typeAndInstance[0] = JobTypes::FrameSubmissionPart1;
- submissionStatsPart1.jobId.typeAndInstance[1] = 0;
- submissionStatsPart1.threadId = reinterpret_cast<quint64>(QThread::currentThreadId());
- submissionStatsPart1.startTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
- submissionStatsPart2.jobId.typeAndInstance[0] = JobTypes::FrameSubmissionPart2;
- submissionStatsPart2.jobId.typeAndInstance[1] = 0;
- submissionStatsPart2.threadId = reinterpret_cast<quint64>(QThread::currentThreadId());
-#endif
-
- if (canRender()) {
- { // Scoped to destroy surfaceLock
- QSurface *surface = nullptr;
- for (const Render::RenderView *rv: renderViews) {
- surface = rv->surface();
- if (surface)
- break;
- }
-
- SurfaceLocker surfaceLock(surface);
- const bool surfaceIsValid = (surface && surfaceLock.isSurfaceValid());
- if (surfaceIsValid) {
- // Reset state for each draw if we don't have complete control of the context
- if (!m_ownedContext)
- m_submissionContext->setCurrentStateSet(nullptr);
- beganDrawing = m_submissionContext->beginDrawing(surface);
- if (beganDrawing) {
- // 1) Execute commands for buffer uploads, texture updates, shader loading first
- updateGLResources();
- // 2) Update VAO and copy data into commands to allow concurrent submission
- prepareCommandsSubmission(renderViews);
- preprocessingComplete = true;
- }
- }
- }
- // 2) Proceed to next frame and start preparing frame n + 1
- m_renderQueue->reset();
- locker.unlock(); // Done protecting RenderQueue
- m_vsyncFrameAdvanceService->proceedToNextFrame();
- hasCleanedQueueAndProceeded = true;
-
-#if QT_CONFIG(qt3d_profile_jobs)
- if (preprocessingComplete) {
- submissionStatsPart2.startTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
- submissionStatsPart1.endTime = submissionStatsPart2.startTime;
- }
-#endif
- // Only try to submit the RenderViews if the preprocessing was successful
- // This part of the submission is happening in parallel to the RV building for the next frame
- if (preprocessingComplete) {
- // 3) Submit the render commands for frame n (making sure we never reference something that could be changing)
- // Render using current device state and renderer configuration
- submissionData = submitRenderViews(renderViews);
-
- // Perform any required cleanup of the Graphics resources (Buffers deleted, Shader deleted...)
- cleanGraphicsResources();
- }
- }
-
-#if QT_CONFIG(qt3d_profile_jobs)
- // Execute the pending shell commands
- m_commandExecuter->performAsynchronousCommandExecution(renderViews);
-#endif
-
- // Delete all the RenderViews which will clear the allocators
- // that were used for their allocation
- qDeleteAll(renderViews);
-
-#if QT_CONFIG(qt3d_profile_jobs)
- if (preprocessingComplete) {
- // Save submission elapsed time
- submissionStatsPart2.endTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
- // Note this is safe since proceedToNextFrame is the one going to trigger
- // the write to the file, and this is performed after this step
- Qt3DCore::QThreadPooler::addSubmissionLogStatsEntry(submissionStatsPart1);
- Qt3DCore::QThreadPooler::addSubmissionLogStatsEntry(submissionStatsPart2);
- Profiling::GLTimeRecorder::writeResults();
- }
-#endif
- }
-
- // Only reset renderQueue and proceed to next frame if the submission
- // succeeded or if we are using a render thread and that is wasn't performed
- // already
-
- // If hasCleanedQueueAndProceeded isn't true this implies that something went wrong
- // with the rendering and/or the renderqueue is incomplete from some reason
- // (in the case of scene3d the render jobs may be taking too long ....)
- // or alternatively it could be complete but empty (RenderQueue of size 0)
- if (!hasCleanedQueueAndProceeded &&
- (m_renderThread || queueIsComplete || queueIsEmpty)) {
- // RenderQueue was full but something bad happened when
- // trying to render it and therefore proceedToNextFrame was not called
- // Note: in this case the renderQueue mutex is still locked
-
- // Reset the m_renderQueue so that we won't try to render
- // with a queue used by a previous frame with corrupted content
- // if the current queue was correctly submitted
- m_renderQueue->reset();
-
- // We allow the RenderTickClock service to proceed to the next frame
- // In turn this will allow the aspect manager to request a new set of jobs
- // to be performed for each aspect
- m_vsyncFrameAdvanceService->proceedToNextFrame();
- }
-
- // Perform the last swapBuffers calls after the proceedToNextFrame
- // as this allows us to gain a bit of time for the preparation of the
- // next frame
- // Finish up with last surface used in the list of RenderViews
- if (beganDrawing) {
- SurfaceLocker surfaceLock(submissionData.surface);
- // Finish up with last surface used in the list of RenderViews
- m_submissionContext->endDrawing(submissionData.lastBoundFBOId == m_submissionContext->defaultFBO() && surfaceLock.isSurfaceValid());
- }
-}
-
-// Called by RenderViewJobs
-// When the frameQueue is complete and we are using a renderThread
-// we allow the render thread to proceed
-void Renderer::enqueueRenderView(Render::RenderView *renderView, int submitOrder)
-{
- QMutexLocker locker(m_renderQueue->mutex()); // Prevent out of order execution
- // We cannot use a lock free primitive here because:
- // - QVector is not thread safe
- // - Even if the insert is made correctly, the isFrameComplete call
- // could be invalid since depending on the order of execution
- // the counter could be complete but the renderview not yet added to the
- // buffer depending on whichever order the cpu decides to process this
- const bool isQueueComplete = m_renderQueue->queueRenderView(renderView, submitOrder);
- locker.unlock(); // We're done protecting the queue at this point
- if (isQueueComplete) {
- if (m_renderThread && m_running.load())
- Q_ASSERT(m_submitRenderViewsSemaphore.available() == 0);
- m_submitRenderViewsSemaphore.release(1);
- }
-}
-
-bool Renderer::canRender() const
-{
- // Make sure that we've not been told to terminate
- if (m_renderThread && !m_running.load()) {
- qCDebug(Rendering) << "RenderThread termination requested whilst waiting";
- return false;
- }
-
- // TO DO: Check if all surfaces have been destroyed...
- // It may be better if the last window to be closed trigger a call to shutdown
- // Rather than having checks for the surface everywhere
-
- return true;
-}
-
-bool Renderer::isReadyToSubmit()
-{
- // If we are using a render thread, make sure that
- // we've been told to render before rendering
- if (m_renderThread) { // Prevent ouf of order execution
- m_submitRenderViewsSemaphore.acquire(1);
-
- // Check if shutdown has been requested
- if (m_running.load() == 0)
- return false;
-
- // When using Thread rendering, the semaphore should only
- // be released when the frame queue is complete and there's
- // something to render
- // The case of shutdown should have been handled just before
- Q_ASSERT(m_renderQueue->isFrameQueueComplete());
- }
- return true;
-}
-
-// Main thread
-QVariant Renderer::executeCommand(const QStringList &args)
-{
-#if QT_CONFIG(qt3d_profile_jobs)
- return m_commandExecuter->executeCommand(args);
-#else
- Q_UNUSED(args);
-#endif
- return QVariant();
-}
-
-/*!
- \internal
- Called in the context of the aspect thread from QRenderAspect::onRegistered
-*/
-void Renderer::setOffscreenSurfaceHelper(OffscreenSurfaceHelper *helper)
-{
- QMutexLocker locker(&m_offscreenSurfaceMutex);
- m_offscreenHelper = helper;
-}
-
-QSurfaceFormat Renderer::format()
-{
- return m_format;
-}
-
-// When this function is called, we must not be processing the commands for frame n+1
-void Renderer::prepareCommandsSubmission(const QVector<RenderView *> &renderViews)
-{
- OpenGLVertexArrayObject *vao = nullptr;
- QHash<HVao, bool> updatedTable;
-
- for (RenderView *rv: renderViews) {
- const QVector<RenderCommand *> commands = rv->commands();
- for (RenderCommand *command : commands) {
- // Update/Create VAO
- if (command->m_type == RenderCommand::Draw) {
- Geometry *rGeometry = m_nodesManager->data<Geometry, GeometryManager>(command->m_geometry);
- GeometryRenderer *rGeometryRenderer = m_nodesManager->data<GeometryRenderer, GeometryRendererManager>(command->m_geometryRenderer);
- Shader *shader = m_nodesManager->data<Shader, ShaderManager>(command->m_shader);
-
- // We should never have inserted a command for which these are null
- // in the first place
- Q_ASSERT(rGeometry && rGeometryRenderer && shader);
-
- // The VAO should be created only once for a QGeometry and a ShaderProgram
- // Manager should have a VAO Manager that are indexed by QMeshData and Shader
- // RenderCommand should have a handle to the corresponding VAO for the Mesh and Shader
- HVao vaoHandle;
-
- // Create VAO or return already created instance associated with command shader/geometry
- // (VAO is emulated if not supported)
- createOrUpdateVAO(command, &vaoHandle, &vao);
- command->m_vao = vaoHandle;
-
- // Avoids redoing the same thing for the same VAO
- if (!updatedTable.contains(vaoHandle)) {
- updatedTable.insert(vaoHandle, true);
-
- // Do we have any attributes that are dirty ?
- const bool requiresPartialVAOUpdate = requiresVAOAttributeUpdate(rGeometry, command);
-
- // If true, we need to reupload all attributes to set the VAO
- // Otherwise only dirty attributes will be updates
- const bool requiresFullVAOUpdate = (!vao->isSpecified()) || (rGeometry->isDirty() || rGeometryRenderer->isDirty());
-
- // Append dirty Geometry to temporary vector
- // so that its dirtiness can be unset later
- if (rGeometry->isDirty())
- m_dirtyGeometry.push_back(rGeometry);
-
- if (!command->m_attributes.isEmpty() && (requiresFullVAOUpdate || requiresPartialVAOUpdate)) {
- Profiling::GLTimeRecorder recorder(Profiling::VAOUpload);
- // Activate shader
- m_submissionContext->activateShader(shader->dna());
- // Bind VAO
- vao->bind();
- // Update or set Attributes and Buffers for the given rGeometry and Command
- // Note: this fills m_dirtyAttributes as well
- if (updateVAOWithAttributes(rGeometry, command, shader, requiresFullVAOUpdate))
- vao->setSpecified(true);
- }
- }
-
- // Unset dirtiness on rGeometryRenderer only
- // The rGeometry may be shared by several rGeometryRenderer
- // so we cannot unset its dirtiness at this point
- if (rGeometryRenderer->isDirty())
- rGeometryRenderer->unsetDirty();
-
- // Prepare the ShaderParameterPack based on the active uniforms of the shader
- shader->prepareUniforms(command->m_parameterPack);
-
- // TO DO: The step below could be performed by the RenderCommand builder job
- { // Scoped to show extent
- command->m_isValid = !command->m_attributes.empty();
- if (!command->m_isValid)
- continue;
-
- // Update the draw command with what's going to be needed for the drawing
- uint primitiveCount = rGeometryRenderer->vertexCount();
- uint estimatedCount = 0;
- Attribute *indexAttribute = nullptr;
- Attribute *indirectAttribute = nullptr;
-
- const QVector<Qt3DCore::QNodeId> attributeIds = rGeometry->attributes();
- for (Qt3DCore::QNodeId attributeId : attributeIds) {
- Attribute *attribute = m_nodesManager->attributeManager()->lookupResource(attributeId);
- switch (attribute->attributeType()) {
- case QAttribute::IndexAttribute:
- indexAttribute = attribute;
- break;
- case QAttribute::DrawIndirectAttribute:
- indirectAttribute = attribute;
- break;
- case QAttribute::VertexAttribute: {
- if (command->m_attributes.contains(attribute->nameId()))
- estimatedCount = qMax(attribute->count(), estimatedCount);
- break;
- }
- default:
- Q_UNREACHABLE();
- break;
- }
- }
-
- command->m_drawIndexed = (indexAttribute != nullptr);
- command->m_drawIndirect = (indirectAttribute != nullptr);
-
- // Update the draw command with all the information required for the drawing
- if (command->m_drawIndexed) {
- command->m_indexAttributeDataType = GraphicsContext::glDataTypeFromAttributeDataType(indexAttribute->vertexBaseType());
- command->m_indexAttributeByteOffset = indexAttribute->byteOffset() + rGeometryRenderer->indexBufferByteOffset();
- }
-
- // Note: we only care about the primitiveCount when using direct draw calls
- // For indirect draw calls it is assumed the buffer was properly set already
- if (command->m_drawIndirect) {
- command->m_indirectAttributeByteOffset = indirectAttribute->byteOffset();
- command->m_indirectDrawBuffer = m_nodesManager->bufferManager()->lookupHandle(indirectAttribute->bufferId());
- } else {
- // Use the count specified by the GeometryRender
- // If not specify use the indexAttribute count if present
- // Otherwise tries to use the count from the attribute with the highest count
- if (primitiveCount == 0) {
- if (indexAttribute)
- primitiveCount = indexAttribute->count();
- else
- primitiveCount = estimatedCount;
- }
- }
-
- command->m_primitiveCount = primitiveCount;
- command->m_primitiveType = rGeometryRenderer->primitiveType();
- command->m_primitiveRestartEnabled = rGeometryRenderer->primitiveRestartEnabled();
- command->m_restartIndexValue = rGeometryRenderer->restartIndexValue();
- command->m_firstInstance = rGeometryRenderer->firstInstance();
- command->m_instanceCount = rGeometryRenderer->instanceCount();
- command->m_firstVertex = rGeometryRenderer->firstVertex();
- command->m_indexOffset = rGeometryRenderer->indexOffset();
- command->m_verticesPerPatch = rGeometryRenderer->verticesPerPatch();
- } // scope
- } else if (command->m_type == RenderCommand::Compute) {
- Shader *shader = m_nodesManager->data<Shader, ShaderManager>(command->m_shader);
- Q_ASSERT(shader);
-
- // Prepare the ShaderParameterPack based on the active uniforms of the shader
- shader->prepareUniforms(command->m_parameterPack);
- }
- }
- }
-
- // Make sure we leave nothing bound
- if (vao)
- vao->release();
-
- // Unset dirtiness on Geometry and Attributes
- // Note: we cannot do it in the loop above as we want to be sure that all
- // the VAO which reference the geometry/attributes are properly updated
- for (Attribute *attribute : qAsConst(m_dirtyAttributes))
- attribute->unsetDirty();
- m_dirtyAttributes.clear();
-
- for (Geometry *geometry : qAsConst(m_dirtyGeometry))
- geometry->unsetDirty();
- m_dirtyGeometry.clear();
-}
-
-// Executed in a job
-void Renderer::lookForAbandonedVaos()
-{
- const QVector<HVao> activeVaos = m_nodesManager->vaoManager()->activeHandles();
- for (const HVao &handle : activeVaos) {
- OpenGLVertexArrayObject *vao = m_nodesManager->vaoManager()->data(handle);
-
- // Make sure to only mark VAOs for deletion that were already created
- // (ignore those that might be currently under construction in the render thread)
- if (vao && vao->isAbandoned(m_nodesManager->geometryManager(), m_nodesManager->shaderManager())) {
- m_abandonedVaosMutex.lock();
- m_abandonedVaos.push_back(handle);
- m_abandonedVaosMutex.unlock();
- }
- }
-}
-
-// Executed in a job
-void Renderer::lookForDirtyBuffers()
-{
- const QVector<HBuffer> activeBufferHandles = m_nodesManager->bufferManager()->activeHandles();
- for (const HBuffer &handle: activeBufferHandles) {
- Buffer *buffer = m_nodesManager->bufferManager()->data(handle);
- if (buffer->isDirty())
- m_dirtyBuffers.push_back(handle);
- }
-}
-
-void Renderer::lookForDownloadableBuffers()
-{
- m_downloadableBuffers.clear();
- const QVector<HBuffer> activeBufferHandles = m_nodesManager->bufferManager()->activeHandles();
- for (const HBuffer &handle : activeBufferHandles) {
- Buffer *buffer = m_nodesManager->bufferManager()->data(handle);
- if (buffer->access() & QBuffer::Read)
- m_downloadableBuffers.push_back(handle);
- }
-}
-
-// Executed in a job
-void Renderer::lookForDirtyTextures()
-{
- const QVector<HTexture> activeTextureHandles = m_nodesManager->textureManager()->activeHandles();
- for (const HTexture &handle: activeTextureHandles) {
- Texture *texture = m_nodesManager->textureManager()->data(handle);
- // Dirty meaning that something has changed on the texture
- // either properties, parameters, generator or a texture image
- if (texture->dirtyFlags() != Texture::NotDirty)
- m_dirtyTextures.push_back(handle);
- }
-}
-
-// Executed in a job
-void Renderer::reloadDirtyShaders()
-{
- Q_ASSERT(isRunning());
- const QVector<HTechnique> activeTechniques = m_nodesManager->techniqueManager()->activeHandles();
- const QVector<HShaderBuilder> activeBuilders = m_nodesManager->shaderBuilderManager()->activeHandles();
- for (const HTechnique &techniqueHandle : activeTechniques) {
- Technique *technique = m_nodesManager->techniqueManager()->data(techniqueHandle);
- // If api of the renderer matches the one from the technique
- if (technique->isCompatibleWithRenderer()) {
- const auto passIds = technique->renderPasses();
- for (const QNodeId passId : passIds) {
- RenderPass *renderPass = m_nodesManager->renderPassManager()->lookupResource(passId);
- HShader shaderHandle = m_nodesManager->shaderManager()->lookupHandle(renderPass->shaderProgram());
- Shader *shader = m_nodesManager->shaderManager()->data(shaderHandle);
-
- ShaderBuilder *shaderBuilder = nullptr;
- for (const HShaderBuilder &builderHandle : activeBuilders) {
- ShaderBuilder *builder = m_nodesManager->shaderBuilderManager()->data(builderHandle);
- if (builder->shaderProgramId() == shader->peerId()) {
- shaderBuilder = builder;
- break;
- }
- }
-
- if (shaderBuilder) {
- shaderBuilder->setGraphicsApi(*technique->graphicsApiFilter());
-
- for (int i = 0; i <= ShaderBuilder::Compute; i++) {
- const auto builderType = static_cast<ShaderBuilder::ShaderType>(i);
- if (!shaderBuilder->shaderGraph(builderType).isValid())
- continue;
-
- if (shaderBuilder->isShaderCodeDirty(builderType)) {
- shaderBuilder->generateCode(builderType);
- }
-
- QShaderProgram::ShaderType shaderType = QShaderProgram::Vertex;
- switch (builderType) {
- case ShaderBuilder::Vertex:
- shaderType = QShaderProgram::Vertex;
- break;
- case ShaderBuilder::TessellationControl:
- shaderType = QShaderProgram::TessellationControl;
- break;
- case ShaderBuilder::TessellationEvaluation:
- shaderType = QShaderProgram::TessellationEvaluation;
- break;
- case ShaderBuilder::Geometry:
- shaderType = QShaderProgram::Geometry;
- break;
- case ShaderBuilder::Fragment:
- shaderType = QShaderProgram::Fragment;
- break;
- case ShaderBuilder::Compute:
- shaderType = QShaderProgram::Compute;
- break;
- }
-
- const auto code = shaderBuilder->shaderCode(builderType);
- shader->setShaderCode(shaderType, code);
- }
- }
-
- if (Q_UNLIKELY(shader->hasPendingNotifications()))
- shader->submitPendingNotifications();
- // If the shader hasn't be loaded, load it
- if (shader != nullptr && !shader->isLoaded())
- loadShader(shader);
- }
- }
- }
-}
-
-// Render Thread
-void Renderer::updateGLResources()
-{
- {
- Profiling::GLTimeRecorder recorder(Profiling::BufferUpload);
- const QVector<HBuffer> dirtyBufferHandles = std::move(m_dirtyBuffers);
- for (const HBuffer &handle: dirtyBufferHandles) {
- Buffer *buffer = m_nodesManager->bufferManager()->data(handle);
- // Forces creation if it doesn't exit
- // Also note the binding point doesn't really matter here, we just upload data
- if (!m_submissionContext->hasGLBufferForBuffer(buffer))
- m_submissionContext->glBufferForRenderBuffer(buffer, GLBuffer::ArrayBuffer);
- // Update the glBuffer data
- m_submissionContext->updateBuffer(buffer);
- buffer->unsetDirty();
- }
- }
-
- {
- Profiling::GLTimeRecorder recorder(Profiling::TextureUpload);
- const QVector<HTexture> activeTextureHandles = std::move(m_dirtyTextures);
- for (const HTexture &handle: activeTextureHandles) {
- Texture *texture = m_nodesManager->textureManager()->data(handle);
- // Upload/Update texture
- updateTexture(texture);
- }
- }
- // When Textures are cleaned up, their id is saved
- // so that they can be cleaned up in the render thread
- // Note: we perform this step in second so that the previous updateTexture call
- // has a chance to find a shared texture
- const QVector<Qt3DCore::QNodeId> cleanedUpTextureIds = m_nodesManager->textureManager()->takeTexturesIdsToCleanup();
- for (const Qt3DCore::QNodeId textureCleanedUpId: cleanedUpTextureIds) {
- cleanupTexture(m_nodesManager->textureManager()->lookupResource(textureCleanedUpId));
- // We can really release the texture at this point
- m_nodesManager->textureManager()->releaseResource(textureCleanedUpId);
- }
-}
-
-// Render Thread
-void Renderer::updateTexture(Texture *texture)
-{
- // Check that the current texture images are still in place, if not, do not update
- const bool isValid = texture->isValid();
- if (!isValid)
- return;
-
- // For implementing unique, non-shared, non-cached textures.
- // for now, every texture is shared by default
-
- bool isUnique = false;
-
- // TO DO: Update the vector once per frame (or in a job)
- const QVector<HAttachment> activeRenderTargetOutputs = m_nodesManager->attachmentManager()->activeHandles();
- // A texture is unique if it's being reference by a render target output
- for (const HAttachment &attachmentHandle : activeRenderTargetOutputs) {
- RenderTargetOutput *attachment = m_nodesManager->attachmentManager()->data(attachmentHandle);
- if (attachment->textureUuid() == texture->peerId()) {
- isUnique = true;
- break;
- }
- }
-
- // Try to find the associated GLTexture for the backend Texture
- GLTextureManager *glTextureManager = m_nodesManager->glTextureManager();
- GLTexture *glTexture = glTextureManager->lookupResource(texture->peerId());
-
- // No GLTexture associated yet -> create it
- if (glTexture == nullptr) {
- if (isUnique)
- glTextureManager->createUnique(texture);
- else
- glTextureManager->getOrCreateShared(texture);
- texture->unsetDirty();
- return;
- }
-
- // if this texture is a shared texture, we might need to look for a new TextureImpl
- // and abandon the old one
- if (glTextureManager->isShared(glTexture)) {
- glTextureManager->abandon(glTexture, texture);
- // Check if a shared texture should become unique
- if (isUnique)
- glTextureManager->createUnique(texture);
- else
- glTextureManager->getOrCreateShared(texture);
- texture->unsetDirty();
- return;
- }
-
- // this texture node is the only one referring to the GLTexture.
- // we could thus directly modify the texture. Instead, for non-unique textures,
- // we first see if there is already a matching texture present.
- if (!isUnique) {
- GLTexture *newSharedTex = glTextureManager->findMatchingShared(texture);
- if (newSharedTex && newSharedTex != glTexture) {
- glTextureManager->abandon(glTexture, texture);
- glTextureManager->adoptShared(newSharedTex, texture);
- texture->unsetDirty();
- return;
- }
- }
-
- // we hold a reference to a unique or exclusive access to a shared texture
- // we can thus modify the texture directly.
- const Texture::DirtyFlags dirtyFlags = texture->dirtyFlags();
-
- if (dirtyFlags.testFlag(Texture::DirtyProperties) &&
- !glTextureManager->setProperties(glTexture, texture->properties()))
- qWarning() << "[Qt3DRender::TextureNode] updateTexture: TextureImpl.setProperties failed, should be non-shared";
-
- if (dirtyFlags.testFlag(Texture::DirtyParameters) &&
- !glTextureManager->setParameters(glTexture, texture->parameters()))
- qWarning() << "[Qt3DRender::TextureNode] updateTexture: TextureImpl.setParameters failed, should be non-shared";
-
- // Will make the texture requestUpload
- if (dirtyFlags.testFlag(Texture::DirtyImageGenerators) &&
- !glTextureManager->setImages(glTexture, texture->textureImages()))
- qWarning() << "[Qt3DRender::TextureNode] updateTexture: TextureImpl.setGenerators failed, should be non-shared";
-
- // Will make the texture requestUpload
- if (dirtyFlags.testFlag(Texture::DirtyDataGenerator) &&
- !glTextureManager->setGenerator(glTexture, texture->dataGenerator()))
- qWarning() << "[Qt3DRender::TextureNode] updateTexture: TextureImpl.setGenerator failed, should be non-shared";
-
- // Unset the dirty flag on the texture
- texture->unsetDirty();
-}
-
-// Render Thread
-void Renderer::cleanupTexture(const Texture *texture)
-{
- GLTextureManager *glTextureManager = m_nodesManager->glTextureManager();
- GLTexture *glTexture = glTextureManager->lookupResource(texture->peerId());
-
- if (glTexture != nullptr)
- glTextureManager->abandon(glTexture, texture);
-}
-
-void Renderer::downloadGLBuffers()
-{
- lookForDownloadableBuffers();
- const QVector<HBuffer> downloadableHandles = std::move(m_downloadableBuffers);
- for (const HBuffer &handle : downloadableHandles) {
- Buffer *buffer = m_nodesManager->bufferManager()->data(handle);
- QByteArray content = m_submissionContext->downloadBufferContent(buffer);
- m_sendBufferCaptureJob->addRequest(QPair<Buffer*, QByteArray>(buffer, content));
- }
-}
-
-// Happens in RenderThread context when all RenderViewJobs are done
-// Returns the id of the last bound FBO
-Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Render::RenderView *> &renderViews)
-{
- QElapsedTimer timer;
- quint64 queueElapsed = 0;
- timer.start();
-
- const int renderViewsCount = renderViews.size();
- quint64 frameElapsed = queueElapsed;
- m_lastFrameCorrect.store(1); // everything fine until now.....
-
- qCDebug(Memory) << Q_FUNC_INFO << "rendering frame ";
-
- // We might not want to render on the default FBO
- uint lastBoundFBOId = m_submissionContext->boundFrameBufferObject();
- QSurface *surface = nullptr;
- QSurface *previousSurface = nullptr;
- for (const Render::RenderView *rv: renderViews) {
- previousSurface = rv->surface();
- if (previousSurface)
- break;
- }
- QSurface *lastUsedSurface = nullptr;
-
- for (int i = 0; i < renderViewsCount; ++i) {
- // Initialize GraphicsContext for drawing
- // If the RenderView has a RenderStateSet defined
- const RenderView *renderView = renderViews.at(i);
-
- // Check if using the same surface as the previous RenderView.
- // If not, we have to free up the context from the previous surface
- // and make the context current on the new surface
- surface = renderView->surface();
- SurfaceLocker surfaceLock(surface);
-
- // TO DO: Make sure that the surface we are rendering too has not been unset
-
- // For now, if we do not have a surface, skip this renderview
- // TODO: Investigate if it's worth providing a fallback offscreen surface
- // to use when surface is null. Or if we should instead expose an
- // offscreensurface to Qt3D.
- if (!surface || !surfaceLock.isSurfaceValid()) {
- m_lastFrameCorrect.store(0);
- continue;
- }
-
- lastUsedSurface = surface;
- const bool surfaceHasChanged = surface != previousSurface;
-
- if (surfaceHasChanged && previousSurface) {
- const bool swapBuffers = (lastBoundFBOId == m_submissionContext->defaultFBO()) && PlatformSurfaceFilter::isSurfaceValid(previousSurface);
- // We only call swap buffer if we are sure the previous surface is still valid
- m_submissionContext->endDrawing(swapBuffers);
- }
-
- if (surfaceHasChanged) {
- // If we can't make the context current on the surface, skip to the
- // next RenderView. We won't get the full frame but we may get something
- if (!m_submissionContext->beginDrawing(surface)) {
- qWarning() << "Failed to make OpenGL context current on surface";
- m_lastFrameCorrect.store(0);
- continue;
- }
-
- previousSurface = surface;
- lastBoundFBOId = m_submissionContext->boundFrameBufferObject();
- }
-
- // Apply Memory Barrier if needed
- if (renderView->memoryBarrier() != QMemoryBarrier::None)
- m_submissionContext->memoryBarrier(renderView->memoryBarrier());
-
- // Note: the RenderStateSet is allocated once per RV if needed
- // and it contains a list of StateVariant value types
- RenderStateSet *renderViewStateSet = renderView->stateSet();
-
- {
- Profiling::GLTimeRecorder recorder(Profiling::StateUpdate);
- // Set the RV state if not null,
- if (renderViewStateSet != nullptr)
- m_submissionContext->setCurrentStateSet(renderViewStateSet);
- else
- m_submissionContext->setCurrentStateSet(m_defaultRenderStateSet);
- }
-
- // Set RenderTarget ...
- // Activate RenderTarget
- {
- Profiling::GLTimeRecorder recorder(Profiling::RenderTargetUpdate);
- m_submissionContext->activateRenderTarget(renderView->renderTargetId(),
- renderView->attachmentPack(),
- lastBoundFBOId);
- }
-
- {
- Profiling::GLTimeRecorder recorder(Profiling::ClearBuffer);
- // set color, depth, stencil clear values (only if needed)
- auto clearBufferTypes = renderView->clearTypes();
- if (clearBufferTypes & QClearBuffers::ColorBuffer) {
- const QVector4D vCol = renderView->globalClearColorBufferInfo().clearColor;
- m_submissionContext->clearColor(QColor::fromRgbF(vCol.x(), vCol.y(), vCol.z(), vCol.w()));
- }
- if (clearBufferTypes & QClearBuffers::DepthBuffer)
- m_submissionContext->clearDepthValue(renderView->clearDepthValue());
- if (clearBufferTypes & QClearBuffers::StencilBuffer)
- m_submissionContext->clearStencilValue(renderView->clearStencilValue());
-
- // Clear BackBuffer
- m_submissionContext->clearBackBuffer(clearBufferTypes);
-
- // if there are ClearColors set for different draw buffers,
- // clear each of these draw buffers individually now
- const QVector<ClearBufferInfo> clearDrawBuffers = renderView->specificClearColorBufferInfo();
- for (const ClearBufferInfo &clearBuffer : clearDrawBuffers)
- m_submissionContext->clearBufferf(clearBuffer.drawBufferIndex, clearBuffer.clearColor);
- }
-
- // Set the Viewport
- m_submissionContext->setViewport(renderView->viewport(), renderView->surfaceSize() * renderView->devicePixelRatio());
-
- // Execute the render commands
- if (!executeCommandsSubmission(renderView))
- m_lastFrameCorrect.store(0); // something went wrong; make sure to render the next frame!
-
- // executeCommandsSubmission takes care of restoring the stateset to the value
- // of gc->currentContext() at the moment it was called (either
- // renderViewStateSet or m_defaultRenderStateSet)
- if (!renderView->renderCaptureNodeId().isNull()) {
- const QRenderCaptureRequest request = renderView->renderCaptureRequest();
- const QSize size = m_submissionContext->renderTargetSize(renderView->surfaceSize() * renderView->devicePixelRatio());
- QRect rect(QPoint(0, 0), size);
- if (!request.rect.isEmpty())
- rect = rect.intersected(request.rect);
- QImage image;
- if (!rect.isEmpty()) {
- // Bind fbo as read framebuffer
- m_submissionContext->bindFramebuffer(m_submissionContext->activeFBO(), GraphicsHelperInterface::FBORead);
- image = m_submissionContext->readFramebuffer(rect);
- } else {
- qWarning() << "Requested capture rectangle is outside framebuffer";
- }
- Render::RenderCapture *renderCapture =
- static_cast<Render::RenderCapture*>(m_nodesManager->frameGraphManager()->lookupNode(renderView->renderCaptureNodeId()));
- renderCapture->addRenderCapture(request.captureId, image);
- addRenderCaptureSendRequest(renderView->renderCaptureNodeId());
- }
-
- if (renderView->isDownloadBuffersEnable())
- downloadGLBuffers();
-
- // Perform BlitFramebuffer operations
- if (renderView->hasBlitFramebufferInfo()) {
- const auto &blitFramebufferInfo = renderView->blitFrameBufferInfo();
- const QNodeId inputTargetId = blitFramebufferInfo.sourceRenderTargetId;
- const QNodeId outputTargetId = blitFramebufferInfo.destinationRenderTargetId;
- const QRect inputRect = blitFramebufferInfo.sourceRect;
- const QRect outputRect = blitFramebufferInfo.destinationRect;
- const QRenderTargetOutput::AttachmentPoint inputAttachmentPoint = blitFramebufferInfo.sourceAttachmentPoint;
- const QRenderTargetOutput::AttachmentPoint outputAttachmentPoint = blitFramebufferInfo.destinationAttachmentPoint;
- const QBlitFramebuffer::InterpolationMethod interpolationMethod = blitFramebufferInfo.interpolationMethod;
- m_submissionContext->blitFramebuffer(inputTargetId, outputTargetId, inputRect, outputRect, lastBoundFBOId,
- inputAttachmentPoint, outputAttachmentPoint,
- interpolationMethod);
- }
-
-
- frameElapsed = timer.elapsed() - frameElapsed;
- qCDebug(Rendering) << Q_FUNC_INFO << "Submitted Renderview " << i + 1 << "/" << renderViewsCount << "in " << frameElapsed << "ms";
- frameElapsed = timer.elapsed();
- }
-
- // Bind lastBoundFBOId back. Needed also in threaded mode.
- // lastBoundFBOId != m_graphicsContext->activeFBO() when the last FrameGraph leaf node/renderView
- // contains RenderTargetSelector/RenderTarget
- if (lastBoundFBOId != m_submissionContext->activeFBO())
- m_submissionContext->bindFramebuffer(lastBoundFBOId, GraphicsHelperInterface::FBOReadAndDraw);
-
- // Reset state and call doneCurrent if the surface
- // is valid and was actually activated
- if (surface && m_submissionContext->hasValidGLHelper()) {
- // Reset state to the default state if the last stateset is not the
- // defaultRenderStateSet
- if (m_submissionContext->currentStateSet() != m_defaultRenderStateSet)
- m_submissionContext->setCurrentStateSet(m_defaultRenderStateSet);
- }
-
- queueElapsed = timer.elapsed() - queueElapsed;
- qCDebug(Rendering) << Q_FUNC_INFO << "Submission of Queue in " << queueElapsed << "ms <=> " << queueElapsed / renderViewsCount << "ms per RenderView <=> Avg " << 1000.0f / (queueElapsed * 1.0f/ renderViewsCount * 1.0f) << " RenderView/s";
- qCDebug(Rendering) << Q_FUNC_INFO << "Submission Completed in " << timer.elapsed() << "ms";
-
- // Stores the necessary information to safely perform
- // the last swap buffer call
- ViewSubmissionResultData resultData;
- resultData.lastBoundFBOId = lastBoundFBOId;
- resultData.surface = lastUsedSurface;
-
- return resultData;
-}
-
-void Renderer::markDirty(BackendNodeDirtySet changes, BackendNode *node)
-{
- Q_UNUSED(node);
- m_dirtyBits.marked |= changes;
-}
-
-Renderer::BackendNodeDirtySet Renderer::dirtyBits()
-{
- return m_dirtyBits.marked;
-}
-
-#if defined(QT_BUILD_INTERNAL)
-void Renderer::clearDirtyBits(BackendNodeDirtySet changes)
-{
- m_dirtyBits.remaining &= ~changes;
- m_dirtyBits.marked &= ~changes;
-}
-#endif
-
-bool Renderer::shouldRender()
-{
- // Only render if something changed during the last frame, or the last frame
- // was not rendered successfully (or render-on-demand is disabled)
- return (m_settings->renderPolicy() == QRenderSettings::Always
- || m_dirtyBits.marked != 0
- || m_dirtyBits.remaining != 0
- || !m_lastFrameCorrect.load());
-}
-
-void Renderer::skipNextFrame()
-{
- Q_ASSERT(m_settings->renderPolicy() != QRenderSettings::Always);
-
- // make submitRenderViews() actually run
- m_renderQueue->setNoRender();
- m_submitRenderViewsSemaphore.release(1);
-}
-
-// Waits to be told to create jobs for the next frame
-// Called by QRenderAspect jobsToExecute context of QAspectThread
-// Returns all the jobs (and with proper dependency chain) required
-// for the rendering of the scene
-QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
-{
- QVector<QAspectJobPtr> renderBinJobs;
-
- // Create the jobs to build the frame
- const QVector<QAspectJobPtr> bufferJobs = createRenderBufferJobs();
-
- // Remove previous dependencies
- m_calculateBoundingVolumeJob->removeDependency(QWeakPointer<QAspectJob>());
- m_cleanupJob->removeDependency(QWeakPointer<QAspectJob>());
-
- // Set dependencies
- for (const QAspectJobPtr &bufferJob : bufferJobs)
- m_calculateBoundingVolumeJob->addDependency(bufferJob);
-
- m_updateLevelOfDetailJob->setFrameGraphRoot(frameGraphRoot());
-
- const BackendNodeDirtySet dirtyBitsForFrame = m_dirtyBits.marked | m_dirtyBits.remaining;
- m_dirtyBits.marked = 0;
- m_dirtyBits.remaining = 0;
- BackendNodeDirtySet notCleared = 0;
-
- // Add jobs
- const bool entitiesEnabledDirty = dirtyBitsForFrame & AbstractRenderer::EntityEnabledDirty;
- if (entitiesEnabledDirty) {
- renderBinJobs.push_back(m_updateTreeEnabledJob);
- // This dependency is added here because we clear all dependencies
- // at the start of this function.
- m_calculateBoundingVolumeJob->addDependency(m_updateTreeEnabledJob);
- }
-
- if (dirtyBitsForFrame & AbstractRenderer::TransformDirty) {
- renderBinJobs.push_back(m_worldTransformJob);
- renderBinJobs.push_back(m_updateWorldBoundingVolumeJob);
- renderBinJobs.push_back(m_updateShaderDataTransformJob);
- }
-
- if (dirtyBitsForFrame & AbstractRenderer::GeometryDirty) {
- renderBinJobs.push_back(m_calculateBoundingVolumeJob);
- renderBinJobs.push_back(m_updateMeshTriangleListJob);
- }
-
- if (dirtyBitsForFrame & AbstractRenderer::GeometryDirty ||
- dirtyBitsForFrame & AbstractRenderer::TransformDirty) {
- renderBinJobs.push_back(m_expandBoundingVolumeJob);
- }
-
- m_updateSkinningPaletteJob->setDirtyJoints(m_nodesManager->jointManager()->dirtyJoints());
- renderBinJobs.push_back(m_updateSkinningPaletteJob);
- renderBinJobs.push_back(m_updateLevelOfDetailJob);
- renderBinJobs.push_back(m_cleanupJob);
- renderBinJobs.push_back(m_sendRenderCaptureJob);
- renderBinJobs.push_back(m_sendBufferCaptureJob);
- renderBinJobs.append(bufferJobs);
-
- // Jobs to prepare GL Resource upload
- renderBinJobs.push_back(m_vaoGathererJob);
-
- if (dirtyBitsForFrame & AbstractRenderer::BuffersDirty)
- renderBinJobs.push_back(m_bufferGathererJob);
-
- if (dirtyBitsForFrame & AbstractRenderer::TexturesDirty) {
- renderBinJobs.push_back(m_syncTextureLoadingJob);
- renderBinJobs.push_back(m_textureGathererJob);
- }
-
-
- // Layer cache is dependent on layers, layer filters and the enabled flag
- // on entities
- const bool layersDirty = dirtyBitsForFrame & AbstractRenderer::LayersDirty;
- const bool layersCacheNeedsToBeRebuilt = layersDirty || entitiesEnabledDirty;
- const bool materialDirty = dirtyBitsForFrame & AbstractRenderer::MaterialDirty;
-
- QMutexLocker lock(m_renderQueue->mutex());
- if (m_renderQueue->wasReset()) { // Have we rendered yet? (Scene3D case)
- // Traverse the current framegraph. For each leaf node create a
- // RenderView and set its configuration then create a job to
- // populate the RenderView with a set of RenderCommands that get
- // their details from the RenderNodes that are visible to the
- // Camera selected by the framegraph configuration
- FrameGraphVisitor visitor(m_nodesManager->frameGraphManager());
- const QVector<FrameGraphNode *> fgLeaves = visitor.traverse(frameGraphRoot());
-
- // Remove leaf nodes that no longer exist from cache
- const QList<FrameGraphNode *> keys = m_cache.leafNodeCache.keys();
- for (FrameGraphNode *leafNode : keys) {
- if (!fgLeaves.contains(leafNode))
- m_cache.leafNodeCache.remove(leafNode);
- }
-
- const int fgBranchCount = fgLeaves.size();
- for (int i = 0; i < fgBranchCount; ++i) {
- RenderViewBuilder builder(fgLeaves.at(i), i, this);
- builder.setLayerCacheNeedsToBeRebuilt(layersCacheNeedsToBeRebuilt);
- builder.setMaterialGathererCacheNeedsToBeRebuilt(materialDirty);
- builder.prepareJobs();
- renderBinJobs.append(builder.buildJobHierachy());
- }
-
- // Set target number of RenderViews
- m_renderQueue->setTargetRenderViewCount(fgBranchCount);
- } else {
- // FilterLayerEntityJob is part of the RenderViewBuilder jobs and must be run later
- // if none of those jobs are started this frame
- notCleared |= AbstractRenderer::EntityEnabledDirty;
- notCleared |= AbstractRenderer::LayersDirty;
- }
-
- if (isRunning() && m_submissionContext->isInitialized()) {
- if (dirtyBitsForFrame & AbstractRenderer::TechniquesDirty )
- renderBinJobs.push_back(m_filterCompatibleTechniqueJob);
- if (dirtyBitsForFrame & AbstractRenderer::ShadersDirty)
- renderBinJobs.push_back(m_introspectShaderJob);
- } else {
- notCleared |= AbstractRenderer::TechniquesDirty;
- notCleared |= AbstractRenderer::ShadersDirty;
- }
-
- m_dirtyBits.remaining = dirtyBitsForFrame & notCleared;
-
- return renderBinJobs;
-}
-
-QAspectJobPtr Renderer::pickBoundingVolumeJob()
-{
- // Set values on pickBoundingVolumeJob
- RenderSettings *renderSetting = settings();
- if (renderSetting != nullptr) {
- m_pickBoundingVolumeJob->setRenderSettings(renderSetting);
- m_pickBoundingVolumeJob->setFrameGraphRoot(frameGraphRoot());
- m_pickBoundingVolumeJob->setMouseEvents(pendingPickingEvents());
- m_pickBoundingVolumeJob->setKeyEvents(pendingKeyEvents());
- }
-
- return m_pickBoundingVolumeJob;
-}
-
-QAspectJobPtr Renderer::rayCastingJob()
-{
- // Set values on rayCastingJob
- RenderSettings *renderSetting = settings();
- if (renderSetting != nullptr) {
- m_rayCastingJob->setRenderSettings(renderSetting);
- m_rayCastingJob->setFrameGraphRoot(frameGraphRoot());
- }
-
- return m_rayCastingJob;
-}
-
-QAspectJobPtr Renderer::syncTextureLoadingJob()
-{
- return m_syncTextureLoadingJob;
-}
-
-QAspectJobPtr Renderer::expandBoundingVolumeJob()
-{
- return m_expandBoundingVolumeJob;
-}
-
-QAbstractFrameAdvanceService *Renderer::frameAdvanceService() const
-{
- return static_cast<Qt3DCore::QAbstractFrameAdvanceService *>(m_vsyncFrameAdvanceService.data());
-}
-
-// Called by executeCommands
-void Renderer::performDraw(RenderCommand *command)
-{
- // Indirect Draw Calls
- if (command->m_drawIndirect) {
-
- // Bind the indirect draw buffer
- Buffer *indirectDrawBuffer = m_nodesManager->bufferManager()->data(command->m_indirectDrawBuffer);
- if (Q_UNLIKELY(indirectDrawBuffer == nullptr)) {
- qWarning() << "Invalid Indirect Draw Buffer - failed to retrieve Buffer";
- return;
- }
-
- // Get GLBuffer from Buffer;
- GLBuffer *indirectDrawGLBuffer = m_submissionContext->glBufferForRenderBuffer(indirectDrawBuffer, GLBuffer::DrawIndirectBuffer);
- if (Q_UNLIKELY(indirectDrawGLBuffer == nullptr)) {
- qWarning() << "Invalid Indirect Draw Buffer - failed to retrieve GLBuffer";
- return;
- }
-
- // Bind GLBuffer
- const bool successfullyBound = indirectDrawGLBuffer->bind(m_submissionContext.data(), GLBuffer::DrawIndirectBuffer);
-
- if (Q_LIKELY(successfullyBound)) {
- // TO DO: Handle multi draw variants if attribute count > 1
- if (command->m_drawIndexed) {
- m_submissionContext->drawElementsIndirect(command->m_primitiveType,
- command->m_indexAttributeDataType,
- reinterpret_cast<void*>(quintptr(command->m_indirectAttributeByteOffset)));
- } else {
- m_submissionContext->drawArraysIndirect(command->m_primitiveType,
- reinterpret_cast<void*>(quintptr(command->m_indirectAttributeByteOffset)));
- }
- } else {
- qWarning() << "Failed to bind IndirectDrawBuffer";
- }
-
- } else { // Direct Draw Calls
-
- // TO DO: Add glMulti Draw variants
- if (command->m_primitiveType == QGeometryRenderer::Patches)
- m_submissionContext->setVerticesPerPatch(command->m_verticesPerPatch);
-
- if (command->m_primitiveRestartEnabled)
- m_submissionContext->enablePrimitiveRestart(command->m_restartIndexValue);
-
- // TO DO: Add glMulti Draw variants
- if (command->m_drawIndexed) {
- Profiling::GLTimeRecorder recorder(Profiling::DrawElement);
- m_submissionContext->drawElementsInstancedBaseVertexBaseInstance(command->m_primitiveType,
- command->m_primitiveCount,
- command->m_indexAttributeDataType,
- reinterpret_cast<void*>(quintptr(command->m_indexAttributeByteOffset)),
- command->m_instanceCount,
- command->m_indexOffset,
- command->m_firstVertex);
- } else {
- Profiling::GLTimeRecorder recorder(Profiling::DrawArray);
- m_submissionContext->drawArraysInstancedBaseInstance(command->m_primitiveType,
- command->m_firstInstance,
- command->m_primitiveCount,
- command->m_instanceCount,
- command->m_firstVertex);
- }
- }
-
-#if defined(QT3D_RENDER_ASPECT_OPENGL_DEBUG)
- int err = m_graphicsContext->openGLContext()->functions()->glGetError();
- if (err)
- qCWarning(Rendering) << "GL error after drawing mesh:" << QString::number(err, 16);
-#endif
-
- if (command->m_primitiveRestartEnabled)
- m_submissionContext->disablePrimitiveRestart();
-}
-
-void Renderer::performCompute(const RenderView *, RenderCommand *command)
-{
- {
- Profiling::GLTimeRecorder recorder(Profiling::ShaderUpdate);
- m_submissionContext->activateShader(command->m_shaderDna);
- }
- {
- Profiling::GLTimeRecorder recorder(Profiling::UniformUpdate);
- m_submissionContext->setParameters(command->m_parameterPack);
- }
- {
- Profiling::GLTimeRecorder recorder(Profiling::DispatchCompute);
- m_submissionContext->dispatchCompute(command->m_workGroups[0],
- command->m_workGroups[1],
- command->m_workGroups[2]);
- }
- // HACK: Reset the compute flag to dirty
- m_dirtyBits.marked |= AbstractRenderer::ComputeDirty;
-
-#if defined(QT3D_RENDER_ASPECT_OPENGL_DEBUG)
- int err = m_graphicsContext->openGLContext()->functions()->glGetError();
- if (err)
- qCWarning(Rendering) << "GL error after drawing mesh:" << QString::number(err, 16);
-#endif
-}
-
-void Renderer::createOrUpdateVAO(RenderCommand *command,
- HVao *previousVaoHandle,
- OpenGLVertexArrayObject **vao)
-{
- const VAOIdentifier vaoKey(command->m_geometry, command->m_shader);
-
- VAOManager *vaoManager = m_nodesManager->vaoManager();
- command->m_vao = vaoManager->lookupHandle(vaoKey);
-
- if (command->m_vao.isNull()) {
- qCDebug(Rendering) << Q_FUNC_INFO << "Allocating new VAO";
- command->m_vao = vaoManager->getOrAcquireHandle(vaoKey);
- vaoManager->data(command->m_vao)->create(m_submissionContext.data(), vaoKey);
- }
-
- if (*previousVaoHandle != command->m_vao) {
- *previousVaoHandle = command->m_vao;
- *vao = vaoManager->data(command->m_vao);
- }
- Q_ASSERT(*vao);
-}
-
-// Called by RenderView->submit() in RenderThread context
-// Returns true, if all RenderCommands were sent to the GPU
-bool Renderer::executeCommandsSubmission(const RenderView *rv)
-{
- bool allCommandsIssued = true;
-
- // Render drawing commands
- const QVector<RenderCommand *> commands = rv->commands();
-
- // Use the graphicscontext to submit the commands to the underlying
- // graphics API (OpenGL)
-
- // Save the RenderView base stateset
- RenderStateSet *globalState = m_submissionContext->currentStateSet();
- OpenGLVertexArrayObject *vao = nullptr;
-
- for (RenderCommand *command : qAsConst(commands)) {
-
- if (command->m_type == RenderCommand::Compute) { // Compute Call
- performCompute(rv, command);
- } else { // Draw Command
- // Check if we have a valid command that can be drawn
- if (!command->m_isValid) {
- allCommandsIssued = false;
- continue;
- }
-
- vao = m_nodesManager->vaoManager()->data(command->m_vao);
-
- // something may have went wrong when initializing the VAO
- if (!vao->isSpecified()) {
- allCommandsIssued = false;
- continue;
- }
-
- {
- Profiling::GLTimeRecorder recorder(Profiling::ShaderUpdate);
- //// We activate the shader here
- if (!m_submissionContext->activateShader(command->m_shaderDna)) {
- allCommandsIssued = false;
- continue;
- }
- }
-
- {
- Profiling::GLTimeRecorder recorder(Profiling::VAOUpdate);
- // Bind VAO
- vao->bind();
- }
-
- {
- Profiling::GLTimeRecorder recorder(Profiling::UniformUpdate);
- //// Update program uniforms
- if (!m_submissionContext->setParameters(command->m_parameterPack)) {
- allCommandsIssued = false;
- // If we have failed to set uniform (e.g unable to bind a texture)
- // we won't perform the draw call which could show invalid content
- continue;
- }
- }
-
- //// OpenGL State
- // TO DO: Make states not dependendent on their backend node for this step
- // Set state
- RenderStateSet *localState = command->m_stateSet;
-
-
- {
- Profiling::GLTimeRecorder recorder(Profiling::StateUpdate);
- // Merge the RenderCommand state with the globalState of the RenderView
- // Or restore the globalState if no stateSet for the RenderCommand
- if (localState != nullptr) {
- command->m_stateSet->merge(globalState);
- m_submissionContext->setCurrentStateSet(command->m_stateSet);
- } else {
- m_submissionContext->setCurrentStateSet(globalState);
- }
- }
- // All Uniforms for a pass are stored in the QUniformPack of the command
- // Uniforms for Effect, Material and Technique should already have been correctly resolved
- // at that point
-
- //// Draw Calls
- performDraw(command);
- }
- } // end of RenderCommands loop
-
- // We cache the VAO and release it only at the end of the exectute frame
- // We try to minimize VAO binding between RenderCommands
- if (vao)
- vao->release();
-
- // Reset to the state we were in before executing the render commands
- m_submissionContext->setCurrentStateSet(globalState);
-
- return allCommandsIssued;
-}
-
-bool Renderer::updateVAOWithAttributes(Geometry *geometry,
- RenderCommand *command,
- Shader *shader,
- bool forceUpdate)
-{
- m_dirtyAttributes.reserve(m_dirtyAttributes.size() + geometry->attributes().size());
- const auto attributeIds = geometry->attributes();
-
- for (QNodeId attributeId : attributeIds) {
- // TO DO: Improvement we could store handles and use the non locking policy on the attributeManager
- Attribute *attribute = m_nodesManager->attributeManager()->lookupResource(attributeId);
-
- if (attribute == nullptr)
- return false;
-
- Buffer *buffer = m_nodesManager->bufferManager()->lookupResource(attribute->bufferId());
-
- // Buffer update was already performed at this point
- // Just make sure the attribute reference a valid buffer
- if (buffer == nullptr)
- return false;
-
- // Index Attribute
- bool attributeWasDirty = false;
- if (attribute->attributeType() == QAttribute::IndexAttribute) {
- if ((attributeWasDirty = attribute->isDirty()) == true || forceUpdate)
- m_submissionContext->specifyIndices(buffer);
- // Vertex Attribute
- } else if (command->m_attributes.contains(attribute->nameId())) {
- if ((attributeWasDirty = attribute->isDirty()) == true || forceUpdate) {
- // Find the location for the attribute
- const QVector<ShaderAttribute> shaderAttributes = shader->attributes();
- const ShaderAttribute *attributeDescription = nullptr;
- for (const ShaderAttribute &shaderAttribute : shaderAttributes) {
- if (shaderAttribute.m_nameId == attribute->nameId()) {
- attributeDescription = &shaderAttribute;
- break;
- }
- }
- if (!attributeDescription || attributeDescription->m_location < 0)
- return false;
- m_submissionContext->specifyAttribute(attribute, buffer, attributeDescription);
- }
- }
-
- // Append attribute to temporary vector so that its dirtiness
- // can be cleared at the end of the frame
- if (attributeWasDirty)
- m_dirtyAttributes.push_back(attribute);
-
- // Note: We cannot call unsertDirty on the Attribute at this
- // point as we don't know if the attributes are being shared
- // with other geometry / geometryRenderer in which case they still
- // should remain dirty so that VAO for these commands are properly
- // updated
- }
-
- return true;
-}
-
-bool Renderer::requiresVAOAttributeUpdate(Geometry *geometry,
- RenderCommand *command) const
-{
- const auto attributeIds = geometry->attributes();
-
- for (QNodeId attributeId : attributeIds) {
- // TO DO: Improvement we could store handles and use the non locking policy on the attributeManager
- Attribute *attribute = m_nodesManager->attributeManager()->lookupResource(attributeId);
-
- if (attribute == nullptr)
- continue;
-
- if ((attribute->attributeType() == QAttribute::IndexAttribute && attribute->isDirty()) ||
- (command->m_attributes.contains(attribute->nameId()) && attribute->isDirty()))
- return true;
- }
- return false;
-}
-
-// Erase graphics related resources that may become unused after a frame
-void Renderer::cleanGraphicsResources()
-{
- // Clean buffers
- const QVector<Qt3DCore::QNodeId> buffersToRelease = m_nodesManager->bufferManager()->takeBuffersToRelease();
- for (Qt3DCore::QNodeId bufferId : buffersToRelease)
- m_submissionContext->releaseBuffer(bufferId);
-
- // Delete abandoned textures
- const QVector<GLTexture*> abandonedTextures = m_nodesManager->glTextureManager()->takeAbandonedTextures();
- for (GLTexture *tex : abandonedTextures) {
- tex->destroyGLTexture();
- delete tex;
- }
-
- // Delete abandoned VAOs
- m_abandonedVaosMutex.lock();
- const QVector<HVao> abandonedVaos = std::move(m_abandonedVaos);
- m_abandonedVaosMutex.unlock();
- for (const HVao &vaoHandle : abandonedVaos) {
- // might have already been destroyed last frame, but added by the cleanup job before, so
- // check if the VAO is really still existent
- OpenGLVertexArrayObject *vao = m_nodesManager->vaoManager()->data(vaoHandle);
- if (vao) {
- vao->destroy();
- m_nodesManager->vaoManager()->release(vaoHandle);
- }
- }
-}
-
-QList<QPair<QObject *, QMouseEvent>> Renderer::pendingPickingEvents() const
-{
- return m_pickEventFilter->pendingMouseEvents();
-}
-
-QList<QKeyEvent> Renderer::pendingKeyEvents() const
-{
- return m_pickEventFilter->pendingKeyEvents();
-}
-
-const GraphicsApiFilterData *Renderer::contextInfo() const
-{
- return m_submissionContext->contextInfo();
-}
-
-SubmissionContext *Renderer::submissionContext() const
-{
- return m_submissionContext.data();
-}
-
-void Renderer::addRenderCaptureSendRequest(Qt3DCore::QNodeId nodeId)
-{
- if (!m_pendingRenderCaptureSendRequests.contains(nodeId))
- m_pendingRenderCaptureSendRequests.push_back(nodeId);
-}
-
-const QVector<Qt3DCore::QNodeId> Renderer::takePendingRenderCaptureSendRequests()
-{
- return std::move(m_pendingRenderCaptureSendRequests);
-}
-
-// Returns a vector of jobs to be performed for dirty buffers
-// 1 dirty buffer == 1 job, all job can be performed in parallel
-QVector<Qt3DCore::QAspectJobPtr> Renderer::createRenderBufferJobs() const
-{
- const QVector<QNodeId> dirtyBuffers = m_nodesManager->bufferManager()->takeDirtyBuffers();
- QVector<QAspectJobPtr> dirtyBuffersJobs;
- dirtyBuffersJobs.reserve(dirtyBuffers.size());
-
- for (const QNodeId bufId : dirtyBuffers) {
- Render::HBuffer bufferHandle = m_nodesManager->lookupHandle<Render::Buffer, Render::BufferManager, Render::HBuffer>(bufId);
- if (!bufferHandle.isNull()) {
- // Create new buffer job
- auto job = Render::LoadBufferJobPtr::create(bufferHandle);
- job->setNodeManager(m_nodesManager);
- dirtyBuffersJobs.push_back(job);
- }
- }
-
- return dirtyBuffersJobs;
-}
-
-} // namespace Render
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
diff --git a/src/render/backend/renderer_p.h b/src/render/backend/renderer_p.h
deleted file mode 100644
index b4ad0b0fe..000000000
--- a/src/render/backend/renderer_p.h
+++ /dev/null
@@ -1,405 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
-** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
-** 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 QT3DRENDER_RENDER_RENDERER_H
-#define QT3DRENDER_RENDER_RENDERER_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 <Qt3DRender/qrenderaspect.h>
-#include <Qt3DRender/qtechnique.h>
-#include <Qt3DRender/private/shaderparameterpack_p.h>
-#include <Qt3DRender/private/handle_types_p.h>
-#include <Qt3DRender/private/abstractrenderer_p.h>
-#include <Qt3DCore/qaspectjob.h>
-#include <Qt3DRender/private/qt3drender_global_p.h>
-#include <Qt3DRender/private/pickboundingvolumejob_p.h>
-#include <Qt3DRender/private/raycastingjob_p.h>
-#include <Qt3DRender/private/rendersettings_p.h>
-#include <Qt3DRender/private/renderviewinitializerjob_p.h>
-#include <Qt3DRender/private/expandboundingvolumejob_p.h>
-#include <Qt3DRender/private/updateworldtransformjob_p.h>
-#include <Qt3DRender/private/calcboundingvolumejob_p.h>
-#include <Qt3DRender/private/updateshaderdatatransformjob_p.h>
-#include <Qt3DRender/private/framecleanupjob_p.h>
-#include <Qt3DRender/private/updateworldboundingvolumejob_p.h>
-#include <Qt3DRender/private/updatetreeenabledjob_p.h>
-#include <Qt3DRender/private/platformsurfacefilter_p.h>
-#include <Qt3DRender/private/sendrendercapturejob_p.h>
-#include <Qt3DRender/private/sendbuffercapturejob_p.h>
-#include <Qt3DRender/private/genericlambdajob_p.h>
-#include <Qt3DRender/private/updatemeshtrianglelistjob_p.h>
-#include <Qt3DRender/private/filtercompatibletechniquejob_p.h>
-#include <Qt3DRender/private/updateskinningpalettejob_p.h>
-#include <Qt3DRender/private/renderercache_p.h>
-
-#include <QHash>
-#include <QMatrix4x4>
-#include <QObject>
-
-#include <QOpenGLShaderProgram>
-#include <QOpenGLVertexArrayObject>
-#include <QOpenGLBuffer>
-#include <QMutex>
-#include <QWaitCondition>
-#include <QAtomicInt>
-#include <QScopedPointer>
-#include <QSemaphore>
-
-#include <functional>
-
-QT_BEGIN_NAMESPACE
-
-class QSurface;
-class QMouseEvent;
-
-namespace Qt3DCore {
-class QEntity;
-class QFrameAllocator;
-class QEventFilterService;
-}
-
-namespace Qt3DRender {
-
-class QCamera;
-class QMaterial;
-class QShaderProgram;
-class QMesh;
-class QRenderPass;
-class QAbstractShapeMesh;
-struct GraphicsApiFilterData;
-class QSceneImporter;
-
-#if QT_CONFIG(qt3d_profile_jobs)
-namespace Debug {
-class CommandExecuter;
-}
-#endif
-
-namespace Render {
-
-class CameraLens;
-class SubmissionContext;
-class FrameGraphNode;
-class Material;
-class Technique;
-class Shader;
-class Entity;
-class RenderCommand;
-class RenderQueue;
-class RenderView;
-class Effect;
-class RenderPass;
-class RenderThread;
-class CommandThread;
-class RenderStateSet;
-class VSyncFrameAdvanceService;
-class PickEventFilter;
-class NodeManagers;
-class ShaderCache;
-
-class UpdateLevelOfDetailJob;
-typedef QSharedPointer<UpdateLevelOfDetailJob> UpdateLevelOfDetailJobPtr;
-
-using SynchronizerJobPtr = GenericLambdaJobPtr<std::function<void()>>;
-using IntrospectShadersJobPtr = GenericLambdaJobPtr<std::function<void()>>;
-
-class QT3DRENDERSHARED_PRIVATE_EXPORT Renderer : public AbstractRenderer
-{
-public:
- explicit Renderer(QRenderAspect::RenderType type);
- ~Renderer();
-
- void dumpInfo() const override;
- API api() const override { return AbstractRenderer::OpenGL; }
-
- qint64 time() const override;
- void setTime(qint64 time) override;
-
- void setNodeManagers(NodeManagers *managers) override;
- void setServices(Qt3DCore::QServiceLocator *services) override;
- void setSurfaceExposed(bool exposed) override;
-
- NodeManagers *nodeManagers() const override;
- Qt3DCore::QServiceLocator *services() const override { return m_services; }
-
- void initialize() override;
- void shutdown() override;
- void releaseGraphicsResources() override;
-
- void render() override;
- void doRender(bool scene3dBlocking = false) override;
- void cleanGraphicsResources() override;
-
- bool isRunning() const override { return m_running.load(); }
-
- void setSceneRoot(Qt3DCore::QBackendNodeFactory *factory, Entity *sgRoot) override;
- Entity *sceneRoot() const override { return m_renderSceneRoot; }
-
- FrameGraphNode *frameGraphRoot() const override;
-
- void markDirty(BackendNodeDirtySet changes, BackendNode *node) override;
- BackendNodeDirtySet dirtyBits() override;
-
-#if defined(QT_BUILD_INTERNAL)
- void clearDirtyBits(BackendNodeDirtySet changes) override;
-#endif
- bool shouldRender() override;
- void skipNextFrame() override;
-
- QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() override;
- Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() override;
- Qt3DCore::QAspectJobPtr rayCastingJob() override;
- Qt3DCore::QAspectJobPtr syncTextureLoadingJob() override;
- Qt3DCore::QAspectJobPtr expandBoundingVolumeJob() override;
-
- QVector<Qt3DCore::QAspectJobPtr> createRenderBufferJobs() const;
-
- inline FrameCleanupJobPtr frameCleanupJob() const { return m_cleanupJob; }
- inline UpdateShaderDataTransformJobPtr updateShaderDataTransformJob() const { return m_updateShaderDataTransformJob; }
- inline CalculateBoundingVolumeJobPtr calculateBoundingVolumeJob() const { return m_calculateBoundingVolumeJob; }
- inline UpdateTreeEnabledJobPtr updateTreeEnabledJob() const { return m_updateTreeEnabledJob; }
- inline UpdateWorldTransformJobPtr updateWorldTransformJob() const { return m_worldTransformJob; }
- inline UpdateWorldBoundingVolumeJobPtr updateWorldBoundingVolumeJob() const { return m_updateWorldBoundingVolumeJob; }
- inline UpdateLevelOfDetailJobPtr updateLevelOfDetailJob() const { return m_updateLevelOfDetailJob; }
- inline UpdateMeshTriangleListJobPtr updateMeshTriangleListJob() const { return m_updateMeshTriangleListJob; }
- inline FilterCompatibleTechniqueJobPtr filterCompatibleTechniqueJob() const { return m_filterCompatibleTechniqueJob; }
- inline SynchronizerJobPtr textureLoadSyncJob() const { return m_syncTextureLoadingJob; }
- inline UpdateSkinningPaletteJobPtr updateSkinningPaletteJob() const { return m_updateSkinningPaletteJob; }
- inline IntrospectShadersJobPtr introspectShadersJob() const { return m_introspectShaderJob; }
- inline Qt3DCore::QAspectJobPtr bufferGathererJob() const { return m_bufferGathererJob; }
- inline Qt3DCore::QAspectJobPtr textureGathererJob() const { return m_textureGathererJob; }
-
- Qt3DCore::QAbstractFrameAdvanceService *frameAdvanceService() const override;
-
- void registerEventFilter(Qt3DCore::QEventFilterService *service) override;
-
- void setSettings(RenderSettings *settings) override;
- RenderSettings *settings() const override;
- QOpenGLContext *shareContext() const override;
-
-
- // Executed in secondary GL thread
- void loadShader(Shader *shader) const override;
-
-
- void updateGLResources();
- void updateTexture(Texture *texture);
- void cleanupTexture(const Texture *texture);
- void downloadGLBuffers();
- void blitFramebuffer(Qt3DCore::QNodeId inputRenderTargetId,
- Qt3DCore::QNodeId outputRenderTargetId,
- QRect inputRect,
- QRect outputRect,
- GLuint defaultFramebuffer);
-
- void prepareCommandsSubmission(const QVector<RenderView *> &renderViews);
- bool executeCommandsSubmission(const RenderView *rv);
- bool updateVAOWithAttributes(Geometry *geometry,
- RenderCommand *command,
- Shader *shader,
- bool forceUpdate);
-
- bool requiresVAOAttributeUpdate(Geometry *geometry,
- RenderCommand *command) const;
-
- void setOpenGLContext(QOpenGLContext *context);
- const GraphicsApiFilterData *contextInfo() const;
- SubmissionContext *submissionContext() const;
-
- inline RenderStateSet *defaultRenderState() const { return m_defaultRenderStateSet; }
-
- QList<QPair<QObject*, QMouseEvent>> pendingPickingEvents() const;
- QList<QKeyEvent> pendingKeyEvents() const;
-
- void addRenderCaptureSendRequest(Qt3DCore::QNodeId nodeId);
- const QVector<Qt3DCore::QNodeId> takePendingRenderCaptureSendRequests();
-
- void enqueueRenderView(RenderView *renderView, int submitOrder);
- bool isReadyToSubmit();
-
- QVariant executeCommand(const QStringList &args) override;
- void setOffscreenSurfaceHelper(OffscreenSurfaceHelper *helper) override;
- QSurfaceFormat format() override;
-
- struct ViewSubmissionResultData
- {
- ViewSubmissionResultData()
- : lastBoundFBOId(0)
- , surface(nullptr)
- {}
-
- uint lastBoundFBOId;
- QSurface *surface;
- };
-
- ViewSubmissionResultData submitRenderViews(const QVector<Render::RenderView *> &renderViews);
-
- RendererCache *cache() { return &m_cache; }
-
-#ifdef QT3D_RENDER_UNIT_TESTS
-public:
-#else
-
-private:
-#endif
- bool canRender() const;
-
- Qt3DCore::QServiceLocator *m_services;
- NodeManagers *m_nodesManager;
-
- // Frame graph root
- Qt3DCore::QNodeId m_frameGraphRootUuid;
-
- Entity *m_renderSceneRoot;
-
- // Fail safe values that we can use if a RenderCommand
- // is missing a shader
- RenderStateSet *m_defaultRenderStateSet;
- ShaderParameterPack m_defaultUniformPack;
-
- QScopedPointer<SubmissionContext> m_submissionContext;
- QSurfaceFormat m_format;
-
- RenderQueue *m_renderQueue;
- QScopedPointer<RenderThread> m_renderThread;
- QScopedPointer<CommandThread> m_commandThread;
- QScopedPointer<VSyncFrameAdvanceService> m_vsyncFrameAdvanceService;
-
- QSemaphore m_submitRenderViewsSemaphore;
- QSemaphore m_waitForInitializationToBeCompleted;
-
- QAtomicInt m_running;
-
- QScopedPointer<PickEventFilter> m_pickEventFilter;
-
- QVector<Attribute *> m_dirtyAttributes;
- QVector<Geometry *> m_dirtyGeometry;
- QAtomicInt m_exposed;
-
- struct DirtyBits {
- BackendNodeDirtySet marked = 0; // marked dirty since last job build
- BackendNodeDirtySet remaining = 0; // remaining dirty after jobs have finished
- };
- DirtyBits m_dirtyBits;
-
- QAtomicInt m_lastFrameCorrect;
- QOpenGLContext *m_glContext;
- QOpenGLContext *m_shareContext;
- mutable QMutex m_shareContextMutex;
- ShaderCache *m_shaderCache;
- PickBoundingVolumeJobPtr m_pickBoundingVolumeJob;
- RayCastingJobPtr m_rayCastingJob;
-
- qint64 m_time;
-
- RenderSettings *m_settings;
-
- UpdateShaderDataTransformJobPtr m_updateShaderDataTransformJob;
- FrameCleanupJobPtr m_cleanupJob;
- UpdateWorldTransformJobPtr m_worldTransformJob;
- ExpandBoundingVolumeJobPtr m_expandBoundingVolumeJob;
- CalculateBoundingVolumeJobPtr m_calculateBoundingVolumeJob;
- UpdateWorldBoundingVolumeJobPtr m_updateWorldBoundingVolumeJob;
- UpdateTreeEnabledJobPtr m_updateTreeEnabledJob;
- SendRenderCaptureJobPtr m_sendRenderCaptureJob;
- SendBufferCaptureJobPtr m_sendBufferCaptureJob;
- UpdateSkinningPaletteJobPtr m_updateSkinningPaletteJob;
- UpdateLevelOfDetailJobPtr m_updateLevelOfDetailJob;
- UpdateMeshTriangleListJobPtr m_updateMeshTriangleListJob;
- FilterCompatibleTechniqueJobPtr m_filterCompatibleTechniqueJob;
-
- QVector<Qt3DCore::QNodeId> m_pendingRenderCaptureSendRequests;
-
- void performDraw(RenderCommand *command);
- void performCompute(const RenderView *rv, RenderCommand *command);
- void createOrUpdateVAO(RenderCommand *command,
- HVao *previousVAOHandle,
- OpenGLVertexArrayObject **vao);
-
- GenericLambdaJobPtr<std::function<void ()>> m_bufferGathererJob;
- GenericLambdaJobPtr<std::function<void ()>> m_vaoGathererJob;
- GenericLambdaJobPtr<std::function<void ()>> m_textureGathererJob;
- IntrospectShadersJobPtr m_introspectShaderJob;
-
- SynchronizerJobPtr m_syncTextureLoadingJob;
-
- void lookForAbandonedVaos();
- void lookForDirtyBuffers();
- void lookForDownloadableBuffers();
- void lookForDirtyTextures();
- void reloadDirtyShaders();
-
- QMutex m_abandonedVaosMutex;
- QVector<HVao> m_abandonedVaos;
-
- QVector<HBuffer> m_dirtyBuffers;
- QVector<HBuffer> m_downloadableBuffers;
- QVector<HTexture> m_dirtyTextures;
-
- bool m_ownedContext;
-
- OffscreenSurfaceHelper *m_offscreenHelper;
- QMutex m_offscreenSurfaceMutex;
-
-#if QT_CONFIG(qt3d_profile_jobs)
- QScopedPointer<Qt3DRender::Debug::CommandExecuter> m_commandExecuter;
- friend class Qt3DRender::Debug::CommandExecuter;
-#endif
-
- QMetaObject::Connection m_contextConnection;
- RendererCache m_cache;
-};
-
-} // namespace Render
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
-
-#endif // QT3DRENDER_RENDER_RENDERER_H
diff --git a/src/render/backend/renderercache_p.h b/src/render/backend/renderercache_p.h
deleted file mode 100644
index 2aa50d131..000000000
--- a/src/render/backend/renderercache_p.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 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 QT3DRENDER_RENDER_RENDERERCACHE_P_H
-#define QT3DRENDER_RENDER_RENDERERCACHE_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 <Qt3DRender/QFrameGraphNode>
-
-#include <Qt3DRender/private/entity_p.h>
-#include <Qt3DRender/private/renderviewjobutils_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-
-namespace Render {
-
-struct RendererCache
-{
- struct LeafNodeData
- {
- QVector<Entity *> filterEntitiesByLayer;
- MaterialParameterGathererData materialParameterGatherer;
- };
-
- QHash<FrameGraphNode *, LeafNodeData> leafNodeCache;
-
- QMutex *mutex() { return &m_mutex; }
-
-private:
- QMutex m_mutex;
-};
-
-} // namespace Render
-
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
-
-#endif // QT3DRENDER_RENDER_RENDERERCACHE_P_H
diff --git a/src/render/backend/renderqueue.cpp b/src/render/backend/renderqueue.cpp
deleted file mode 100644
index bd9d3ee59..000000000
--- a/src/render/backend/renderqueue.cpp
+++ /dev/null
@@ -1,133 +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$
-**
-****************************************************************************/
-
-#include "renderqueue_p.h"
-#include <Qt3DRender/private/renderview_p.h>
-#include <QThread>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-
-namespace Render {
-
-RenderQueue::RenderQueue()
- : m_noRender(false)
- , m_wasReset(true)
- , m_targetRenderViewCount(0)
- , m_currentRenderViewCount(0)
- , m_currentWorkQueue(1)
-{
-}
-
-int RenderQueue::currentRenderViewCount() const
-{
- return m_currentRenderViewCount;
-}
-
-/*
- * In case the framegraph changed or when the current number of render queue
- * needs to be reset.
- */
-void RenderQueue::reset()
-{
- m_currentRenderViewCount = 0;
- m_targetRenderViewCount = 0;
- m_currentWorkQueue.clear();
- m_noRender = false;
- m_wasReset = true;
-}
-
-void RenderQueue::setNoRender()
-{
- Q_ASSERT(m_targetRenderViewCount == 0);
- m_noRender = true;
-}
-
-/*
- * Queue up a RenderView for the frame being built.
- * Thread safe as this is called from the renderer which is locked.
- * Returns true if the renderView is complete
- */
-bool RenderQueue::queueRenderView(RenderView *renderView, uint submissionOrderIndex)
-{
- Q_ASSERT(!m_noRender);
- m_currentWorkQueue[submissionOrderIndex] = renderView;
- ++m_currentRenderViewCount;
- Q_ASSERT(m_currentRenderViewCount <= m_targetRenderViewCount);
- return isFrameQueueComplete();
-}
-
-/*
- * Called by the Rendering Thread to retrieve the a frame queue to render.
- * A call to reset is required after rendering of the frame. Otherwise under some
- * conditions the current but then invalidated frame queue could be reused.
- */
-QVector<RenderView *> RenderQueue::nextFrameQueue()
-{
- return m_currentWorkQueue;
-}
-
-/*
- * Sets the number \a targetRenderViewCount of RenderView objects that make up a frame.
- */
-void RenderQueue::setTargetRenderViewCount(int targetRenderViewCount)
-{
- Q_ASSERT(!m_noRender);
- m_targetRenderViewCount = targetRenderViewCount;
- m_currentWorkQueue.resize(targetRenderViewCount);
- m_wasReset = false;
-}
-
-/*
- * Returns true if all the RenderView objects making up the current frame have been queued.
- * Returns false otherwise.
- * \note a frameQueue or size 0 is considered incomplete.
- */
-bool RenderQueue::isFrameQueueComplete() const
-{
- return (m_noRender
- || (m_targetRenderViewCount > 0 && m_targetRenderViewCount == m_currentRenderViewCount));
-}
-
-} // namespace Render
-
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
diff --git a/src/render/backend/renderqueue_p.h b/src/render/backend/renderqueue_p.h
deleted file mode 100644
index e565115f2..000000000
--- a/src/render/backend/renderqueue_p.h
+++ /dev/null
@@ -1,102 +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 QT3DRENDER_RENDER_RENDERQUEUE_H
-#define QT3DRENDER_RENDER_RENDERQUEUE_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 <QVector>
-#include <QtGlobal>
-#include <QMutex>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-
-namespace Render {
-
-class RenderView;
-
-class Q_AUTOTEST_EXPORT RenderQueue
-{
-public:
- RenderQueue();
-
- void setTargetRenderViewCount(int targetRenderViewCount);
- int targetRenderViewCount() const { return m_targetRenderViewCount; }
- int currentRenderViewCount() const;
- bool isFrameQueueComplete() const;
-
- bool queueRenderView(RenderView *renderView, uint submissionOrderIndex);
- QVector<RenderView *> nextFrameQueue();
- void reset();
-
- void setNoRender();
- inline bool isNoRender() const { return m_noRender; }
-
- inline bool wasReset() const { return m_wasReset; }
-
- inline QMutex *mutex() { return &m_mutex; }
-
-private:
- bool m_noRender;
- bool m_wasReset;
- int m_targetRenderViewCount;
- int m_currentRenderViewCount;
- QVector<RenderView *> m_currentWorkQueue;
- QMutex m_mutex;
-};
-
-} // namespace Render
-
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
-
-#endif // QT3DRENDER_RENDER_RENDERQUEUE_H
diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp
deleted file mode 100644
index c29448570..000000000
--- a/src/render/backend/renderview.cpp
+++ /dev/null
@@ -1,1108 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
-** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
-** 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 "renderview_p.h"
-#include <Qt3DRender/qmaterial.h>
-#include <Qt3DRender/qrenderaspect.h>
-#include <Qt3DRender/qrendertarget.h>
-#include <Qt3DRender/qabstractlight.h>
-#include <Qt3DRender/private/sphere_p.h>
-
-#include <Qt3DRender/private/cameraselectornode_p.h>
-#include <Qt3DRender/private/framegraphnode_p.h>
-#include <Qt3DRender/private/layerfilternode_p.h>
-#include <Qt3DRender/private/qparameter_p.h>
-#include <Qt3DRender/private/cameralens_p.h>
-#include <Qt3DRender/private/rendercommand_p.h>
-#include <Qt3DRender/private/effect_p.h>
-#include <Qt3DRender/private/entity_p.h>
-#include <Qt3DRender/private/renderer_p.h>
-#include <Qt3DRender/private/nodemanagers_p.h>
-#include <Qt3DRender/private/layer_p.h>
-#include <Qt3DRender/private/renderlogging_p.h>
-#include <Qt3DRender/private/renderpassfilternode_p.h>
-#include <Qt3DRender/private/renderpass_p.h>
-#include <Qt3DRender/private/geometryrenderer_p.h>
-#include <Qt3DRender/private/renderstateset_p.h>
-#include <Qt3DRender/private/techniquefilternode_p.h>
-#include <Qt3DRender/private/viewportnode_p.h>
-#include <Qt3DRender/private/buffermanager_p.h>
-#include <Qt3DRender/private/geometryrenderermanager_p.h>
-#include <Qt3DRender/private/rendercapture_p.h>
-#include <Qt3DRender/private/buffercapture_p.h>
-#include <Qt3DRender/private/stringtoint_p.h>
-#include <Qt3DCore/qentity.h>
-#include <QtGui/qsurface.h>
-#include <algorithm>
-
-#include <QDebug>
-#if defined(QT3D_RENDER_VIEW_JOB_TIMINGS)
-#include <QElapsedTimer>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-namespace Render {
-
-
-namespace {
-
-// register our QNodeId's as a metatype during program loading
-const int Q_DECL_UNUSED qNodeIdTypeId = qMetaTypeId<Qt3DCore::QNodeId>();
-
-const int MAX_LIGHTS = 8;
-
-#define LIGHT_POSITION_NAME QLatin1String(".position")
-#define LIGHT_TYPE_NAME QLatin1String(".type")
-#define LIGHT_COLOR_NAME QLatin1String(".color")
-#define LIGHT_INTENSITY_NAME QLatin1String(".intensity")
-
-int LIGHT_COUNT_NAME_ID = 0;
-int LIGHT_POSITION_NAMES[MAX_LIGHTS];
-int LIGHT_TYPE_NAMES[MAX_LIGHTS];
-int LIGHT_COLOR_NAMES[MAX_LIGHTS];
-int LIGHT_INTENSITY_NAMES[MAX_LIGHTS];
-QString LIGHT_STRUCT_NAMES[MAX_LIGHTS];
-
-} // anonymous namespace
-
-bool wasInitialized = false;
-RenderView::StandardUniformsNameToTypeHash RenderView::ms_standardUniformSetters;
-
-
-RenderView::StandardUniformsNameToTypeHash RenderView::initializeStandardUniformSetters()
-{
- RenderView::StandardUniformsNameToTypeHash setters;
-
- setters.insert(StringToInt::lookupId(QLatin1String("modelMatrix")), ModelMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("viewMatrix")), ViewMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("projectionMatrix")), ProjectionMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("modelView")), ModelViewMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("viewProjectionMatrix")), ViewProjectionMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("modelViewProjection")), ModelViewProjectionMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("mvp")), ModelViewProjectionMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("inverseModelMatrix")), InverseModelMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("inverseViewMatrix")), InverseViewMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("inverseProjectionMatrix")), InverseProjectionMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("inverseModelView")), InverseModelViewMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("inverseViewProjectionMatrix")), InverseViewProjectionMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("inverseModelViewProjection")), InverseModelViewProjectionMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("modelNormalMatrix")), ModelNormalMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("modelViewNormal")), ModelViewNormalMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("viewportMatrix")), ViewportMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("inverseViewportMatrix")), InverseViewportMatrix);
- setters.insert(StringToInt::lookupId(QLatin1String("aspectRatio")), AspectRatio);
- setters.insert(StringToInt::lookupId(QLatin1String("exposure")), Exposure);
- setters.insert(StringToInt::lookupId(QLatin1String("gamma")), Gamma);
- setters.insert(StringToInt::lookupId(QLatin1String("time")), Time);
- setters.insert(StringToInt::lookupId(QLatin1String("eyePosition")), EyePosition);
- setters.insert(StringToInt::lookupId(QLatin1String("skinningPalette[0]")), SkinningPalette);
-
- return setters;
-}
-
-// TODO: Move this somewhere global where GraphicsContext::setViewport() can use it too
-static QRectF resolveViewport(const QRectF &fractionalViewport, const QSize &surfaceSize)
-{
- return QRectF(fractionalViewport.x() * surfaceSize.width(),
- (1.0 - fractionalViewport.y() - fractionalViewport.height()) * surfaceSize.height(),
- fractionalViewport.width() * surfaceSize.width(),
- fractionalViewport.height() * surfaceSize.height());
-}
-
-static Matrix4x4 getProjectionMatrix(const CameraLens *lens)
-{
- if (!lens)
- qWarning() << "[Qt3D Renderer] No Camera Lens found. Add a CameraSelector to your Frame Graph or make sure that no entities will be rendered.";
- return lens ? lens->projection() : Matrix4x4();
-}
-
-UniformValue RenderView::standardUniformValue(RenderView::StandardUniform standardUniformType,
- Entity *entity,
- const Matrix4x4 &model) const
-{
- switch (standardUniformType) {
- case ModelMatrix:
- return UniformValue(model);
- case ViewMatrix:
- return UniformValue(m_data.m_viewMatrix);
- case ProjectionMatrix:
- return UniformValue(getProjectionMatrix(m_data.m_renderCameraLens));
- case ModelViewMatrix:
- return UniformValue(m_data.m_viewMatrix * model);
- case ViewProjectionMatrix:
- return UniformValue(getProjectionMatrix(m_data.m_renderCameraLens) * m_data.m_viewMatrix);
- case ModelViewProjectionMatrix:
- return UniformValue(m_data.m_viewProjectionMatrix * model);
- case InverseModelMatrix:
- return UniformValue(model.inverted());
- case InverseViewMatrix:
- return UniformValue(m_data.m_viewMatrix.inverted());
- case InverseProjectionMatrix: {
- return UniformValue(getProjectionMatrix(m_data.m_renderCameraLens).inverted());
- }
- case InverseModelViewMatrix:
- return UniformValue((m_data.m_viewMatrix * model).inverted());
- case InverseViewProjectionMatrix: {
- const Matrix4x4 viewProjectionMatrix = getProjectionMatrix(m_data.m_renderCameraLens) * m_data.m_viewMatrix;
- return UniformValue(viewProjectionMatrix.inverted());
- }
- case InverseModelViewProjectionMatrix:
- return UniformValue((m_data.m_viewProjectionMatrix * model).inverted());
- case ModelNormalMatrix:
- return UniformValue(convertToQMatrix4x4(model).normalMatrix());
- case ModelViewNormalMatrix:
- return UniformValue(convertToQMatrix4x4(m_data.m_viewMatrix * model).normalMatrix());
- case ViewportMatrix: {
- QMatrix4x4 viewportMatrix;
- // TO DO: Implement on Matrix4x4
- viewportMatrix.viewport(resolveViewport(m_viewport, m_surfaceSize));
- return UniformValue(Matrix4x4(viewportMatrix));
- }
- case InverseViewportMatrix: {
- QMatrix4x4 viewportMatrix;
- // TO DO: Implement on Matrix4x4
- viewportMatrix.viewport(resolveViewport(m_viewport, m_surfaceSize));
- return UniformValue(Matrix4x4(viewportMatrix.inverted()));
- }
- case AspectRatio:
- return float(m_surfaceSize.width()) / float(m_surfaceSize.height());
- case Exposure:
- return UniformValue(m_data.m_renderCameraLens ? m_data.m_renderCameraLens->exposure() : 0.0f);
- case Gamma:
- return UniformValue(m_gamma);
- case Time:
- return UniformValue(float(m_renderer->time() / 1000000000.0f));
- case EyePosition:
- return UniformValue(m_data.m_eyePos);
- case SkinningPalette: {
- const Armature *armature = entity->renderComponent<Armature>();
- if (!armature) {
- qCWarning(Jobs, "Requesting skinningPalette uniform but no armature set on entity");
- return UniformValue();
- }
- return armature->skinningPaletteUniform();
- }
- default:
- Q_UNREACHABLE();
- return UniformValue();
- }
-}
-
-RenderView::RenderView()
- : m_isDownloadBuffersEnable(false)
- , m_hasBlitFramebufferInfo(false)
- , m_renderer(nullptr)
- , m_devicePixelRatio(1.)
- , m_viewport(QRectF(0.0f, 0.0f, 1.0f, 1.0f))
- , m_gamma(2.2f)
- , m_surface(nullptr)
- , m_clearBuffer(QClearBuffers::None)
- , m_stateSet(nullptr)
- , m_noDraw(false)
- , m_compute(false)
- , m_frustumCulling(false)
- , m_memoryBarrier(QMemoryBarrier::None)
- , m_environmentLight(nullptr)
-{
- m_workGroups[0] = 1;
- m_workGroups[1] = 1;
- m_workGroups[2] = 1;
-
- if (Q_UNLIKELY(!wasInitialized)) {
- // Needed as we can control the init order of static/global variables across compile units
- // and this hash relies on the static StringToInt class
- wasInitialized = true;
- RenderView::ms_standardUniformSetters = RenderView::initializeStandardUniformSetters();
- LIGHT_COUNT_NAME_ID = StringToInt::lookupId(QLatin1String("lightCount"));
- for (int i = 0; i < MAX_LIGHTS; ++i) {
- Q_STATIC_ASSERT_X(MAX_LIGHTS < 10, "can't use the QChar trick anymore");
- LIGHT_STRUCT_NAMES[i] = QLatin1String("lights[") + QLatin1Char(char('0' + i)) + QLatin1Char(']');
- LIGHT_POSITION_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_POSITION_NAME);
- LIGHT_TYPE_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_TYPE_NAME);
- LIGHT_COLOR_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_COLOR_NAME);
- LIGHT_INTENSITY_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_INTENSITY_NAME);
- }
- }
-}
-
-RenderView::~RenderView()
-{
- delete m_stateSet;
- for (RenderCommand *command : qAsConst(m_commands)) {
- delete command->m_stateSet;
- delete command;
- }
-}
-
-namespace {
-
-template<int SortType>
-struct AdjacentSubRangeFinder
-{
- static bool adjacentSubRange(RenderCommand *, RenderCommand *)
- {
- Q_UNREACHABLE();
- return false;
- }
-};
-
-template<>
-struct AdjacentSubRangeFinder<QSortPolicy::StateChangeCost>
-{
- static bool adjacentSubRange(RenderCommand *a, RenderCommand *b)
- {
- return a->m_changeCost == b->m_changeCost;
- }
-};
-
-template<>
-struct AdjacentSubRangeFinder<QSortPolicy::BackToFront>
-{
- static bool adjacentSubRange(RenderCommand *a, RenderCommand *b)
- {
- return a->m_depth == b->m_depth;
- }
-};
-
-template<>
-struct AdjacentSubRangeFinder<QSortPolicy::Material>
-{
- static bool adjacentSubRange(RenderCommand *a, RenderCommand *b)
- {
- return a->m_shaderDna == b->m_shaderDna;
- }
-};
-
-template<>
-struct AdjacentSubRangeFinder<QSortPolicy::FrontToBack>
-{
- static bool adjacentSubRange(RenderCommand *a, RenderCommand *b)
- {
- return a->m_depth == b->m_depth;
- }
-};
-
-template<typename Predicate>
-int advanceUntilNonAdjacent(const QVector<RenderCommand *> &commands,
- const int beg, const int end, Predicate pred)
-{
- int i = beg + 1;
- while (i < end) {
- if (!pred(*(commands.begin() + beg), *(commands.begin() + i)))
- break;
- ++i;
- }
- return i;
-}
-
-
-using CommandIt = QVector<RenderCommand *>::iterator;
-
-template<int SortType>
-struct SubRangeSorter
-{
- static void sortSubRange(CommandIt begin, const CommandIt end)
- {
- Q_UNUSED(begin);
- Q_UNUSED(end);
- Q_UNREACHABLE();
- }
-};
-
-template<>
-struct SubRangeSorter<QSortPolicy::StateChangeCost>
-{
- static void sortSubRange(CommandIt begin, const CommandIt end)
- {
- std::stable_sort(begin, end, [] (RenderCommand *a, RenderCommand *b) {
- return a->m_changeCost > b->m_changeCost;
- });
- }
-};
-
-template<>
-struct SubRangeSorter<QSortPolicy::BackToFront>
-{
- static void sortSubRange(CommandIt begin, const CommandIt end)
- {
- std::stable_sort(begin, end, [] (RenderCommand *a, RenderCommand *b) {
- return a->m_depth > b->m_depth;
- });
- }
-};
-
-template<>
-struct SubRangeSorter<QSortPolicy::Material>
-{
- static void sortSubRange(CommandIt begin, const CommandIt end)
- {
- // First we sort by shaderDNA
- std::stable_sort(begin, end, [] (RenderCommand *a, RenderCommand *b) {
- return a->m_shaderDna > b->m_shaderDna;
- });
- }
-};
-
-template<>
-struct SubRangeSorter<QSortPolicy::FrontToBack>
-{
- static void sortSubRange(CommandIt begin, const CommandIt end)
- {
- std::stable_sort(begin, end, [] (RenderCommand *a, RenderCommand *b) {
- return a->m_depth < b->m_depth;
- });
- }
-};
-
-int findSubRange(const QVector<RenderCommand *> &commands,
- const int begin, const int end,
- const QSortPolicy::SortType sortType)
-{
- switch (sortType) {
- case QSortPolicy::StateChangeCost:
- return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::StateChangeCost>::adjacentSubRange);
- case QSortPolicy::BackToFront:
- return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::BackToFront>::adjacentSubRange);
- case QSortPolicy::Material:
- return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::Material>::adjacentSubRange);
- case QSortPolicy::FrontToBack:
- return advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::FrontToBack>::adjacentSubRange);
- default:
- Q_UNREACHABLE();
- return end;
- }
-}
-
-void sortByMaterial(QVector<RenderCommand *> &commands, int begin, const int end)
-{
- // We try to arrange elements so that their rendering cost is minimized for a given shader
- int rangeEnd = advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::Material>::adjacentSubRange);
- while (begin != end) {
- if (begin + 1 < rangeEnd) {
- std::stable_sort(commands.begin() + begin + 1, commands.begin() + rangeEnd, [] (RenderCommand *a, RenderCommand *b){
- return a->m_material.handle() < b->m_material.handle();
- });
- }
- begin = rangeEnd;
- rangeEnd = advanceUntilNonAdjacent(commands, begin, end, AdjacentSubRangeFinder<QSortPolicy::Material>::adjacentSubRange);
- }
-}
-
-void sortCommandRange(QVector<RenderCommand *> &commands, int begin, const int end, const int level,
- const QVector<Qt3DRender::QSortPolicy::SortType> &sortingTypes)
-{
- if (level >= sortingTypes.size())
- return;
-
- switch (sortingTypes.at(level)) {
- case QSortPolicy::StateChangeCost:
- SubRangeSorter<QSortPolicy::StateChangeCost>::sortSubRange(commands.begin() + begin, commands.begin() + end);
- break;
- case QSortPolicy::BackToFront:
- SubRangeSorter<QSortPolicy::BackToFront>::sortSubRange(commands.begin() + begin, commands.begin() + end);
- break;
- case QSortPolicy::Material:
- // Groups all same shader DNA together
- SubRangeSorter<QSortPolicy::Material>::sortSubRange(commands.begin() + begin, commands.begin() + end);
- // Group all same material together (same parameters most likely)
- sortByMaterial(commands, begin, end);
- break;
- case QSortPolicy::FrontToBack:
- SubRangeSorter<QSortPolicy::FrontToBack>::sortSubRange(commands.begin() + begin, commands.begin() + end);
- break;
- default:
- Q_UNREACHABLE();
- }
-
- // For all sub ranges of adjacent item for sortType[i]
- // Perform filtering with sortType[i + 1]
- int rangeEnd = findSubRange(commands, begin, end, sortingTypes.at(level));
- while (begin != end) {
- sortCommandRange(commands, begin, rangeEnd, level + 1, sortingTypes);
- begin = rangeEnd;
- rangeEnd = findSubRange(commands, begin, end, sortingTypes.at(level));
- }
-}
-
-} // anonymous
-
-void RenderView::sort()
-{
- sortCommandRange(m_commands, 0, m_commands.size(), 0, m_data.m_sortingTypes);
-
- // For RenderCommand with the same shader
- // We compute the adjacent change cost
-
- // Minimize uniform changes
- int i = 0;
- while (i < m_commands.size()) {
- int j = i;
-
- // Advance while commands share the same shader
- while (i < m_commands.size() && m_commands[j]->m_shaderDna == m_commands[i]->m_shaderDna)
- ++i;
-
- if (i - j > 0) { // Several commands have the same shader, so we minimize uniform changes
- PackUniformHash cachedUniforms = m_commands[j++]->m_parameterPack.uniforms();
-
- while (j < i) {
- // We need the reference here as we are modifying the original container
- // not the copy
- PackUniformHash &uniforms = m_commands.at(j)->m_parameterPack.m_uniforms;
- PackUniformHash::iterator it = uniforms.begin();
- const PackUniformHash::iterator end = uniforms.end();
-
- while (it != end) {
- // We are comparing the values:
- // - raw uniform values
- // - the texture Node id if the uniform represents a texture
- // since all textures are assigned texture units before the RenderCommands
- // sharing the same material (shader) are rendered, we can't have the case
- // where two uniforms, referencing the same texture eventually have 2 different
- // texture unit values
- const UniformValue refValue = cachedUniforms.value(it.key());
- if (it.value() == refValue) {
- it = uniforms.erase(it);
- } else {
- cachedUniforms.insert(it.key(), it.value());
- ++it;
- }
- }
- ++j;
- }
- }
- }
-}
-
-void RenderView::setRenderer(Renderer *renderer)
-{
- m_renderer = renderer;
- m_manager = renderer->nodeManagers();
-}
-
-void RenderView::addClearBuffers(const ClearBuffers *cb) {
- QClearBuffers::BufferTypeFlags type = cb->type();
-
- if (type & QClearBuffers::StencilBuffer) {
- m_clearStencilValue = cb->clearStencilValue();
- m_clearBuffer |= QClearBuffers::StencilBuffer;
- }
- if (type & QClearBuffers::DepthBuffer) {
- m_clearDepthValue = cb->clearDepthValue();
- m_clearBuffer |= QClearBuffers::DepthBuffer;
- }
- // keep track of global ClearColor (if set) and collect all DrawBuffer-specific
- // ClearColors
- if (type & QClearBuffers::ColorBuffer) {
- ClearBufferInfo clearBufferInfo;
- clearBufferInfo.clearColor = cb->clearColor();
-
- if (cb->clearsAllColorBuffers()) {
- m_globalClearColorBuffer = clearBufferInfo;
- m_clearBuffer |= QClearBuffers::ColorBuffer;
- } else {
- if (cb->bufferId()) {
- const RenderTargetOutput *targetOutput = m_manager->attachmentManager()->lookupResource(cb->bufferId());
- if (targetOutput) {
- clearBufferInfo.attchmentPoint = targetOutput->point();
- // Note: a job is later performed to find the drawIndex from the buffer attachment point
- // using the AttachmentPack
- m_specificClearColorBuffers.push_back(clearBufferInfo);
- }
- }
- }
- }
-}
-
-// If we are there, we know that entity had a GeometryRenderer + Material
-QVector<RenderCommand *> RenderView::buildDrawRenderCommands(const QVector<Entity *> &entities) const
-{
- // Note: since many threads can be building render commands
- // we need to ensure that the UniformBlockValueBuilder they are using
- // is only accessed from the same thread
- UniformBlockValueBuilder *builder = new UniformBlockValueBuilder();
- builder->shaderDataManager = m_manager->shaderDataManager();
- builder->textureManager = m_manager->textureManager();
- m_localData.setLocalData(builder);
-
- QVector<RenderCommand *> commands;
- commands.reserve(entities.size());
-
- for (Entity *entity : entities) {
- GeometryRenderer *geometryRenderer = nullptr;
- HGeometryRenderer geometryRendererHandle = entity->componentHandle<GeometryRenderer>();
-
- // There is a geometry renderer with geometry
- if ((geometryRenderer = m_manager->geometryRendererManager()->data(geometryRendererHandle)) != nullptr
- && geometryRenderer->isEnabled()
- && !geometryRenderer->geometryId().isNull()) {
-
- const Qt3DCore::QNodeId materialComponentId = entity->componentUuid<Material>();
- const HMaterial materialHandle = entity->componentHandle<Material>();
- const QVector<RenderPassParameterData> renderPassData = m_parameters.value(materialComponentId);
- HGeometry geometryHandle = m_manager->lookupHandle<Geometry, GeometryManager, HGeometry>(geometryRenderer->geometryId());
- Geometry *geometry = m_manager->data<Geometry, GeometryManager>(geometryHandle);
-
- // 1 RenderCommand per RenderPass pass on an Entity with a Mesh
- for (const RenderPassParameterData &passData : renderPassData) {
- // Add the RenderPass Parameters
- RenderCommand *command = new RenderCommand();
-
- // Project the camera-to-object-center vector onto the camera
- // view vector. This gives a depth value suitable as the key
- // for BackToFront sorting.
- command->m_depth = Vector3D::dotProduct(entity->worldBoundingVolume()->center() - m_data.m_eyePos, m_data.m_eyeViewDir);
-
- command->m_geometry = geometryHandle;
- command->m_geometryRenderer = geometryRendererHandle;
- command->m_material = materialHandle;
- // For RenderPass based states we use the globally set RenderState
- // if no renderstates are defined as part of the pass. That means:
- // RenderPass { renderStates: [] } will use the states defined by
- // StateSet in the FrameGraph
- RenderPass *pass = passData.pass;
- if (pass->hasRenderStates()) {
- command->m_stateSet = new RenderStateSet();
- addToRenderStateSet(command->m_stateSet, pass->renderStates(), m_manager->renderStateManager());
-
- // Merge per pass stateset with global stateset
- // so that the local stateset only overrides
- if (m_stateSet != nullptr)
- command->m_stateSet->merge(m_stateSet);
- command->m_changeCost = m_renderer->defaultRenderState()->changeCost(command->m_stateSet);
- }
-
- // Pick which lights to take in to account.
- // For now decide based on the distance by taking the MAX_LIGHTS closest lights.
- // Replace with more sophisticated mechanisms later.
- // Copy vector so that we can sort it concurrently and we only want to sort the one for the current command
- QVector<LightSource> lightSources = m_lightSources;
- if (lightSources.size() > 1) {
- const Vector3D entityCenter = entity->worldBoundingVolume()->center();
- std::sort(lightSources.begin(), lightSources.end(),
- [&] (const LightSource &a, const LightSource &b) {
- const float distA = entityCenter.distanceToPoint(a.entity->worldBoundingVolume()->center());
- const float distB = entityCenter.distanceToPoint(b.entity->worldBoundingVolume()->center());
- return distA < distB;
- });
- }
-
- ParameterInfoList globalParameters = passData.parameterInfo;
- // setShaderAndUniforms can initialize a localData
- // make sure this is cleared before we leave this function
- setShaderAndUniforms(command,
- pass,
- globalParameters,
- entity,
- lightSources.mid(0, std::max(lightSources.size(), MAX_LIGHTS)),
- m_environmentLight);
-
- // Store all necessary information for actual drawing if command is valid
- command->m_isValid = !command->m_attributes.empty();
- if (command->m_isValid) {
- // Update the draw command with what's going to be needed for the drawing
- uint primitiveCount = geometryRenderer->vertexCount();
- uint estimatedCount = 0;
- Attribute *indexAttribute = nullptr;
-
- const QVector<Qt3DCore::QNodeId> attributeIds = geometry->attributes();
- for (Qt3DCore::QNodeId attributeId : attributeIds) {
- Attribute *attribute = m_manager->attributeManager()->lookupResource(attributeId);
- if (attribute->attributeType() == QAttribute::IndexAttribute)
- indexAttribute = attribute;
- else if (command->m_attributes.contains(attribute->nameId()))
- estimatedCount = qMax(attribute->count(), estimatedCount);
- }
-
- // Update the draw command with all the information required for the drawing
- command->m_drawIndexed = (indexAttribute != nullptr);
- if (command->m_drawIndexed) {
- command->m_indexAttributeDataType = GraphicsContext::glDataTypeFromAttributeDataType(indexAttribute->vertexBaseType());
- command->m_indexAttributeByteOffset = indexAttribute->byteOffset();
- }
-
- // Use the count specified by the GeometryRender
- // If not specified use the indexAttribute count if present
- // Otherwise tries to use the count from the attribute with the highest count
- if (primitiveCount == 0) {
- if (indexAttribute)
- primitiveCount = indexAttribute->count();
- else
- primitiveCount = estimatedCount;
- }
-
- command->m_primitiveCount = primitiveCount;
- command->m_primitiveType = geometryRenderer->primitiveType();
- command->m_primitiveRestartEnabled = geometryRenderer->primitiveRestartEnabled();
- command->m_restartIndexValue = geometryRenderer->restartIndexValue();
- command->m_firstInstance = geometryRenderer->firstInstance();
- command->m_instanceCount = geometryRenderer->instanceCount();
- command->m_firstVertex = geometryRenderer->firstVertex();
- command->m_indexOffset = geometryRenderer->indexOffset();
- command->m_verticesPerPatch = geometryRenderer->verticesPerPatch();
- }
-
- commands.append(command);
- }
- }
- }
-
- // We reset the local data once we are done with it
- m_localData.setLocalData(nullptr);
-
- return commands;
-}
-
-QVector<RenderCommand *> RenderView::buildComputeRenderCommands(const QVector<Entity *> &entities) const
-{
- // Note: since many threads can be building render commands
- // we need to ensure that the UniformBlockValueBuilder they are using
- // is only accessed from the same thread
- UniformBlockValueBuilder *builder = new UniformBlockValueBuilder();
- builder->shaderDataManager = m_manager->shaderDataManager();
- builder->textureManager = m_manager->textureManager();
- m_localData.setLocalData(builder);
-
- // If the RenderView contains only a ComputeDispatch then it cares about
- // A ComputeDispatch is also implicitely a NoDraw operation
- // enabled flag
- // layer component
- // material/effect/technique/parameters/filters/
- QVector<RenderCommand *> commands;
- commands.reserve(entities.size());
- for (Entity *entity : entities) {
- ComputeCommand *computeJob = nullptr;
- if ((computeJob = entity->renderComponent<ComputeCommand>()) != nullptr
- && computeJob->isEnabled()) {
-
- const Qt3DCore::QNodeId materialComponentId = entity->componentUuid<Material>();
- const QVector<RenderPassParameterData> renderPassData = m_parameters.value(materialComponentId);
-
- // 1 RenderCommand per RenderPass pass on an Entity with a Mesh
- for (const RenderPassParameterData &passData : renderPassData) {
- // Add the RenderPass Parameters
- ParameterInfoList globalParameters = passData.parameterInfo;
- RenderPass *pass = passData.pass;
- parametersFromParametersProvider(&globalParameters, m_manager->parameterManager(), pass);
-
- RenderCommand *command = new RenderCommand();
- command->m_type = RenderCommand::Compute;
- command->m_workGroups[0] = std::max(m_workGroups[0], computeJob->x());
- command->m_workGroups[1] = std::max(m_workGroups[1], computeJob->y());
- command->m_workGroups[2] = std::max(m_workGroups[2], computeJob->z());
- setShaderAndUniforms(command,
- pass,
- globalParameters,
- entity,
- QVector<LightSource>(),
- nullptr);
- commands.append(command);
- }
- }
- }
-
- // We reset the local data once we are done with it
- m_localData.setLocalData(nullptr);
-
- return commands;
-}
-
-void RenderView::updateMatrices()
-{
- if (m_data.m_renderCameraNode && m_data.m_renderCameraLens && m_data.m_renderCameraLens->isEnabled()) {
- const Matrix4x4 cameraWorld = *(m_data.m_renderCameraNode->worldTransform());
- setViewMatrix(m_data.m_renderCameraLens->viewMatrix(cameraWorld));
-
- setViewProjectionMatrix(m_data.m_renderCameraLens->projection() * viewMatrix());
- //To get the eyePosition of the camera, we need to use the inverse of the
- //camera's worldTransform matrix.
- const Matrix4x4 inverseWorldTransform = viewMatrix().inverted();
- const Vector3D eyePosition(inverseWorldTransform.column(3));
- setEyePosition(eyePosition);
-
- // Get the viewing direction of the camera. Use the normal matrix to
- // ensure non-uniform scale works too.
- const QMatrix3x3 normalMat = convertToQMatrix4x4(m_data.m_viewMatrix).normalMatrix();
- // dir = normalize(QVector3D(0, 0, -1) * normalMat)
- setEyeViewDirection(Vector3D(-normalMat(2, 0), -normalMat(2, 1), -normalMat(2, 2)).normalized());
- }
-}
-
-void RenderView::setUniformValue(ShaderParameterPack &uniformPack, int nameId, const UniformValue &value) const
-{
- // At this point a uniform value can only be a scalar type
- // or a Qt3DCore::QNodeId corresponding to a Texture
- // ShaderData/Buffers would be handled as UBO/SSBO and would therefore
- // not be in the default uniform block
- if (value.valueType() == UniformValue::NodeId) {
- const Qt3DCore::QNodeId *nodeIds = value.constData<Qt3DCore::QNodeId>();
-
- const int uniformArraySize = value.byteSize() / sizeof(Qt3DCore::QNodeId);
- for (int i = 0; i < uniformArraySize; ++i) {
- const Qt3DCore::QNodeId texId = nodeIds[i];
- const Texture *tex = m_manager->textureManager()->lookupResource(texId);
- if (tex != nullptr)
- uniformPack.setTexture(nameId, i, texId);
- }
-
- UniformValue textureValue(uniformArraySize * sizeof(int), UniformValue::TextureValue);
- std::fill(textureValue.data<int>(), textureValue.data<int>() + uniformArraySize, -1);
- uniformPack.setUniform(nameId, textureValue);
- } else {
- uniformPack.setUniform(nameId, value);
- }
-}
-
-void RenderView::setStandardUniformValue(ShaderParameterPack &uniformPack,
- int glslNameId,
- int nameId,
- Entity *entity,
- const Matrix4x4 &worldTransform) const
-{
- uniformPack.setUniform(glslNameId, standardUniformValue(ms_standardUniformSetters[nameId], entity, worldTransform));
-}
-
-void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack,
- Shader *shader,
- const ShaderUniformBlock &block,
- const UniformValue &value) const
-{
- Q_UNUSED(shader)
-
- if (value.valueType() == UniformValue::NodeId) {
-
- Buffer *buffer = nullptr;
- if ((buffer = m_manager->bufferManager()->lookupResource(*value.constData<Qt3DCore::QNodeId>())) != nullptr) {
- BlockToUBO uniformBlockUBO;
- uniformBlockUBO.m_blockIndex = block.m_index;
- uniformBlockUBO.m_bufferID = buffer->peerId();
- uniformBlockUBO.m_needsUpdate = false;
- uniformPack.setUniformBuffer(std::move(uniformBlockUBO));
- // Buffer update to GL buffer will be done at render time
- }
-
-
- //ShaderData *shaderData = nullptr;
- // if ((shaderData = m_manager->shaderDataManager()->lookupResource(value.value<Qt3DCore::QNodeId>())) != nullptr) {
- // UBO are indexed by <ShaderId, ShaderDataId> so that a same QShaderData can be used among different shaders
- // while still making sure that if they have a different layout everything will still work
- // If two shaders define the same block with the exact same layout, in that case the UBO could be shared
- // but how do we know that ? We'll need to compare ShaderUniformBlocks
-
- // Note: we assume that if a buffer is shared across multiple shaders
- // then it implies that they share the same layout
-
- // Temporarly disabled
-
- // BufferShaderKey uboKey(shaderData->peerId(),
- // shader->peerId());
-
- // BlockToUBO uniformBlockUBO;
- // uniformBlockUBO.m_blockIndex = block.m_index;
- // uniformBlockUBO.m_shaderDataID = shaderData->peerId();
- // bool uboNeedsUpdate = false;
-
- // // build UBO at uboId if not created before
- // if (!m_manager->glBufferManager()->contains(uboKey)) {
- // m_manager->glBufferManager()->getOrCreateResource(uboKey);
- // uboNeedsUpdate = true;
- // }
-
- // // If shaderData has been updated (property has changed or one of the nested properties has changed)
- // // foreach property defined in the QShaderData, we try to fill the value of the corresponding active uniform(s)
- // // for all the updated properties (all the properties if the UBO was just created)
- // if (shaderData->updateViewTransform(*m_data->m_viewMatrix) || uboNeedsUpdate) {
- // // Clear previous values remaining in the hash
- // m_data->m_uniformBlockBuilder.activeUniformNamesToValue.clear();
- // // Update only update properties if uboNeedsUpdate is true, otherwise update the whole block
- // m_data->m_uniformBlockBuilder.updatedPropertiesOnly = uboNeedsUpdate;
- // // Retrieve names and description of each active uniforms in the uniform block
- // m_data->m_uniformBlockBuilder.uniforms = shader->activeUniformsForUniformBlock(block.m_index);
- // // Builds the name-value map for the block
- // m_data->m_uniformBlockBuilder.buildActiveUniformNameValueMapStructHelper(shaderData, block.m_name);
- // if (!uboNeedsUpdate)
- // shaderData->markDirty();
- // // copy the name-value map into the BlockToUBO
- // uniformBlockUBO.m_updatedProperties = m_data->m_uniformBlockBuilder.activeUniformNamesToValue;
- // uboNeedsUpdate = true;
- // }
-
- // uniformBlockUBO.m_needsUpdate = uboNeedsUpdate;
- // uniformPack.setUniformBuffer(std::move(uniformBlockUBO));
- // }
- }
-}
-
-void RenderView::setShaderStorageValue(ShaderParameterPack &uniformPack,
- Shader *shader,
- const ShaderStorageBlock &block,
- const UniformValue &value) const
-{
- Q_UNUSED(shader)
- if (value.valueType() == UniformValue::NodeId) {
- Buffer *buffer = nullptr;
- if ((buffer = m_manager->bufferManager()->lookupResource(*value.constData<Qt3DCore::QNodeId>())) != nullptr) {
- BlockToSSBO shaderStorageBlock;
- shaderStorageBlock.m_blockIndex = block.m_index;
- shaderStorageBlock.m_bufferID = buffer->peerId();
- uniformPack.setShaderStorageBuffer(shaderStorageBlock);
- // Buffer update to GL buffer will be done at render time
- }
- }
-}
-
-void RenderView::setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack, Shader *shader, ShaderData *shaderData, const QString &structName) const
-{
- UniformBlockValueBuilder *builder = m_localData.localData();
- builder->activeUniformNamesToValue.clear();
-
- // Set the view matrix to be used to transform "Transformed" properties in the ShaderData
- builder->viewMatrix = m_data.m_viewMatrix;
- // Force to update the whole block
- builder->updatedPropertiesOnly = false;
- // Retrieve names and description of each active uniforms in the uniform block
- builder->uniforms = shader->activeUniformsForUniformBlock(-1);
- // Build name-value map for the block
- builder->buildActiveUniformNameValueMapStructHelper(shaderData, structName);
- // Set uniform values for each entrie of the block name-value map
- QHash<int, QVariant>::const_iterator activeValuesIt = builder->activeUniformNamesToValue.constBegin();
- const QHash<int, QVariant>::const_iterator activeValuesEnd = builder->activeUniformNamesToValue.constEnd();
-
- // TO DO: Make the ShaderData store UniformValue
- while (activeValuesIt != activeValuesEnd) {
- setUniformValue(uniformPack, activeValuesIt.key(), UniformValue::fromVariant(activeValuesIt.value()));
- ++activeValuesIt;
- }
-}
-
-void RenderView::setShaderAndUniforms(RenderCommand *command,
- RenderPass *rPass,
- ParameterInfoList &parameters,
- Entity *entity,
- const QVector<LightSource> &activeLightSources,
- EnvironmentLight *environmentLight) const
-{
- // The VAO Handle is set directly in the renderer thread so as to avoid having to use a mutex here
- // Set shader, technique, and effect by basically doing :
- // ShaderProgramManager[MaterialManager[frontentEntity->id()]->Effect->Techniques[TechniqueFilter->name]->RenderPasses[RenderPassFilter->name]];
- // The Renderer knows that if one of those is null, a default material / technique / effect as to be used
-
- // Find all RenderPasses (in order) matching values set in the RenderPassFilter
- // Get list of parameters for the Material, Effect, and Technique
- // For each ParameterBinder in the RenderPass -> create a QUniformPack
- // Once that works, improve that to try and minimize QUniformPack updates
-
- if (rPass != nullptr) {
- // Index Shader by Shader UUID
- command->m_shader = m_manager->lookupHandle<Shader, ShaderManager, HShader>(rPass->shaderProgram());
- Shader *shader = m_manager->data<Shader, ShaderManager>(command->m_shader);
- if (shader != nullptr && shader->isLoaded()) {
- command->m_shaderDna = shader->dna();
-
- // Builds the QUniformPack, sets shader standard uniforms and store attributes name / glname bindings
- // If a parameter is defined and not found in the bindings it is assumed to be a binding of Uniform type with the glsl name
- // equals to the parameter name
- const QVector<int> uniformNamesIds = shader->uniformsNamesIds();
- const QVector<int> uniformBlockNamesIds = shader->uniformBlockNamesIds();
- const QVector<int> shaderStorageBlockNamesIds = shader->storageBlockNamesIds();
- const QVector<int> attributeNamesIds = shader->attributeNamesIds();
-
- // Set fragData Name and index
- // Later on we might want to relink the shader if attachments have changed
- // But for now we set them once and for all
- QHash<QString, int> fragOutputs;
- if (!m_renderTarget.isNull() && !shader->isLoaded()) {
- const auto atts = m_attachmentPack.attachments();
- for (const Attachment &att : atts) {
- if (att.m_point <= QRenderTargetOutput::Color15)
- fragOutputs.insert(att.m_name, att.m_point);
- }
- }
-
- if (!uniformNamesIds.isEmpty() || !attributeNamesIds.isEmpty() ||
- !shaderStorageBlockNamesIds.isEmpty() || !attributeNamesIds.isEmpty()) {
-
- // Set default standard uniforms without bindings
- const Matrix4x4 worldTransform = *(entity->worldTransform());
- for (const int uniformNameId : uniformNamesIds) {
- if (ms_standardUniformSetters.contains(uniformNameId))
- setStandardUniformValue(command->m_parameterPack, uniformNameId, uniformNameId, entity, worldTransform);
- }
-
- // Set default attributes
- for (const int attributeNameId : attributeNamesIds)
- command->m_attributes.push_back(attributeNameId);
-
- // Parameters remaining could be
- // -> uniform scalar / vector
- // -> uniform struct / arrays
- // -> uniform block / array (4.3)
- // -> ssbo block / array (4.3)
-
- ParameterInfoList::const_iterator it = parameters.cbegin();
- const ParameterInfoList::const_iterator parametersEnd = parameters.cend();
-
- while (it != parametersEnd) {
- Parameter *param = m_manager->data<Parameter, ParameterManager>(it->handle);
- const UniformValue &uniformValue = param->uniformValue();
- if (uniformNamesIds.contains(it->nameId)) { // Parameter is a regular uniform
- setUniformValue(command->m_parameterPack, it->nameId, uniformValue);
- } else if (uniformBlockNamesIds.indexOf(it->nameId) != -1) { // Parameter is a uniform block
- setUniformBlockValue(command->m_parameterPack, shader, shader->uniformBlockForBlockNameId(it->nameId), uniformValue);
- } else if (shaderStorageBlockNamesIds.indexOf(it->nameId) != -1) { // Parameters is a SSBO
- setShaderStorageValue(command->m_parameterPack, shader, shader->storageBlockForBlockNameId(it->nameId), uniformValue);
- } else { // Parameter is a struct
- ShaderData *shaderData = nullptr;
- if (uniformValue.valueType() == UniformValue::NodeId &&
- (shaderData = m_manager->shaderDataManager()->lookupResource(*uniformValue.constData<Qt3DCore::QNodeId>())) != nullptr) {
- // Try to check if we have a struct or array matching a QShaderData parameter
- setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, StringToInt::lookupString(it->nameId));
- }
- // Otherwise: param unused by current shader
- }
- ++it;
- }
-
- // Lights
-
- int lightIdx = 0;
- for (const LightSource &lightSource : activeLightSources) {
- if (lightIdx == MAX_LIGHTS)
- break;
- Entity *lightEntity = lightSource.entity;
- const Vector3D worldPos = lightEntity->worldBoundingVolume()->center();
- for (Light *light : lightSource.lights) {
- if (!light->isEnabled())
- continue;
-
- ShaderData *shaderData = m_manager->shaderDataManager()->lookupResource(light->shaderData());
- if (!shaderData)
- continue;
-
- if (lightIdx == MAX_LIGHTS)
- break;
-
- // Note: implicit conversion of values to UniformValue
- setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[lightIdx], worldPos);
- setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[lightIdx], int(QAbstractLight::PointLight));
- setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[lightIdx], Vector3D(1.0f, 1.0f, 1.0f));
- setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[lightIdx], 0.5f);
-
- // There is no risk in doing that even if multithreaded
- // since we are sure that a shaderData is unique for a given light
- // and won't ever be referenced as a Component either
- Matrix4x4 *worldTransform = lightEntity->worldTransform();
- if (worldTransform)
- shaderData->updateWorldTransform(*worldTransform);
-
- setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, LIGHT_STRUCT_NAMES[lightIdx]);
- ++lightIdx;
- }
- }
-
- if (uniformNamesIds.contains(LIGHT_COUNT_NAME_ID))
- setUniformValue(command->m_parameterPack, LIGHT_COUNT_NAME_ID, UniformValue(qMax(1, lightIdx)));
-
- // If no active light sources and no environment light, add a default light
- if (activeLightSources.isEmpty() && !environmentLight) {
- // Note: implicit conversion of values to UniformValue
- setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[0], Vector3D(10.0f, 10.0f, 0.0f));
- setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[0], int(QAbstractLight::PointLight));
- setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[0], Vector3D(1.0f, 1.0f, 1.0f));
- setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[0], 0.5f);
- }
-
- // Environment Light
- int envLightCount = 0;
- if (environmentLight && environmentLight->isEnabled()) {
- ShaderData *shaderData = m_manager->shaderDataManager()->lookupResource(environmentLight->shaderData());
- if (shaderData) {
- setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, QStringLiteral("envLight"));
- envLightCount = 1;
- }
- }
- setUniformValue(command->m_parameterPack, StringToInt::lookupId(QStringLiteral("envLightCount")), envLightCount);
- }
- // Set frag outputs in the shaders if hash not empty
- if (!fragOutputs.isEmpty())
- shader->setFragOutputs(fragOutputs);
- }
- }
- else {
- qCWarning(Render::Backend) << Q_FUNC_INFO << "Using default effect as none was provided";
- }
-}
-
-bool RenderView::hasBlitFramebufferInfo() const
-{
- return m_hasBlitFramebufferInfo;
-}
-
-void RenderView::setHasBlitFramebufferInfo(bool hasBlitFramebufferInfo)
-{
- m_hasBlitFramebufferInfo = hasBlitFramebufferInfo;
-}
-
-BlitFramebufferInfo RenderView::blitFrameBufferInfo() const
-{
- return m_blitFrameBufferInfo;
-}
-
-void RenderView::setBlitFrameBufferInfo(const BlitFramebufferInfo &blitFrameBufferInfo)
-{
- m_blitFrameBufferInfo = blitFrameBufferInfo;
-}
-
-bool RenderView::isDownloadBuffersEnable() const
-{
- return m_isDownloadBuffersEnable;
-}
-
-void RenderView::setIsDownloadBuffersEnable(bool isDownloadBuffersEnable)
-{
- m_isDownloadBuffersEnable = isDownloadBuffersEnable;
-}
-
-} // namespace Render
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
diff --git a/src/render/backend/renderview_p.h b/src/render/backend/renderview_p.h
deleted file mode 100644
index cb3c74917..000000000
--- a/src/render/backend/renderview_p.h
+++ /dev/null
@@ -1,392 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
-** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
-** 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 QT3DRENDER_RENDER_RENDERVIEW_H
-#define QT3DRENDER_RENDER_RENDERVIEW_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 <Qt3DRender/qparameter.h>
-#include <Qt3DRender/qclearbuffers.h>
-#include <Qt3DRender/qlayerfilter.h>
-#include <Qt3DRender/private/renderer_p.h>
-#include <Qt3DRender/private/clearbuffers_p.h>
-#include <Qt3DRender/private/cameralens_p.h>
-#include <Qt3DRender/private/attachmentpack_p.h>
-#include <Qt3DRender/private/handle_types_p.h>
-#include <Qt3DRender/private/qsortpolicy_p.h>
-#include <Qt3DRender/private/lightsource_p.h>
-#include <Qt3DRender/private/qmemorybarrier_p.h>
-#include <Qt3DRender/private/qrendercapture_p.h>
-#include <Qt3DRender/private/qblitframebuffer_p.h>
-
-#include <Qt3DCore/private/qframeallocator_p.h>
-#include <Qt3DRender/private/aligned_malloc_p.h>
-
-// TODO: Move out once this is all refactored
-#include <Qt3DRender/private/renderviewjobutils_p.h>
-
-#include <QVector>
-#include <QSurface>
-#include <QMutex>
-#include <QColor>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-
-class QRenderPass;
-
-namespace Render {
-
-class Renderer;
-class NodeManagers;
-class RenderCommand;
-class RenderPassFilter;
-class TechniqueFilter;
-class ViewportNode;
-class Effect;
-class RenderPass;
-
-typedef QPair<ShaderUniform, QVariant> ActivePropertyContent;
-typedef QPair<QString, ActivePropertyContent > ActiveProperty;
-
-struct Q_AUTOTEST_EXPORT Plane
-{
- explicit Plane(const Vector4D &planeEquation)
- : planeEquation(planeEquation)
- , normal(Vector3D(planeEquation).normalized())
- , d(planeEquation.w() / Vector3D(planeEquation).length())
- {}
-
- const Vector4D planeEquation;
- const Vector3D normal;
- const float d;
-};
-
-struct Q_AUTOTEST_EXPORT ClearBufferInfo
-{
- int drawBufferIndex = 0;
- QRenderTargetOutput::AttachmentPoint attchmentPoint = QRenderTargetOutput::Color0;
- QVector4D clearColor;
-};
-
-struct Q_AUTOTEST_EXPORT BlitFramebufferInfo
-{
- Qt3DCore::QNodeId sourceRenderTargetId;
- Qt3DCore::QNodeId destinationRenderTargetId;
- QRect sourceRect;
- QRect destinationRect;
- Qt3DRender::QRenderTargetOutput::AttachmentPoint sourceAttachmentPoint;
- Qt3DRender::QRenderTargetOutput::AttachmentPoint destinationAttachmentPoint;
- QBlitFramebuffer::InterpolationMethod interpolationMethod;
-};
-
-// This class is kind of analogous to RenderBin but I want to avoid trampling
-// on that until we get this working
-
-class Q_AUTOTEST_EXPORT RenderView
-{
-public:
- RenderView();
- ~RenderView();
-
- QT3D_ALIGNED_MALLOC_AND_FREE()
-
- // TODO: Add a way to specify a sort predicate for the RenderCommands
- void sort();
-
- void setRenderer(Renderer *renderer);
- inline void setSurfaceSize(const QSize &size) Q_DECL_NOTHROW { m_surfaceSize = size; }
- inline Renderer *renderer() const Q_DECL_NOTHROW { return m_renderer; }
- inline NodeManagers *nodeManagers() const Q_DECL_NOTHROW { return m_manager; }
- inline const QSize &surfaceSize() const Q_DECL_NOTHROW { return m_surfaceSize; }
- inline void setDevicePixelRatio(qreal r) Q_DECL_NOTHROW { m_devicePixelRatio = r; }
- inline qreal devicePixelRatio() const Q_DECL_NOTHROW { return m_devicePixelRatio; }
-
- inline void setRenderCameraLens(CameraLens *renderCameraLens) Q_DECL_NOTHROW { m_data.m_renderCameraLens = renderCameraLens; }
- inline CameraLens *renderCameraLens() const Q_DECL_NOTHROW { return m_data.m_renderCameraLens; }
-
- inline void setRenderCameraEntity(Entity *renderCameraNode) Q_DECL_NOTHROW { m_data.m_renderCameraNode = renderCameraNode; }
- inline Entity *renderCameraEntity() const Q_DECL_NOTHROW { return m_data.m_renderCameraNode; }
-
- inline void setViewMatrix(const Matrix4x4 &viewMatrix) Q_DECL_NOTHROW { m_data.m_viewMatrix = viewMatrix; }
- inline Matrix4x4 viewMatrix() const Q_DECL_NOTHROW { return m_data.m_viewMatrix; }
-
- inline void setViewProjectionMatrix(const Matrix4x4 &viewProjectionMatrix) Q_DECL_NOTHROW { m_data.m_viewProjectionMatrix = viewProjectionMatrix; }
- inline Matrix4x4 viewProjectionMatrix() const Q_DECL_NOTHROW { return m_data.m_viewProjectionMatrix; }
-
- inline void setEyePosition(const Vector3D &eyePos) Q_DECL_NOTHROW { m_data.m_eyePos = eyePos; }
- inline Vector3D eyePosition() const Q_DECL_NOTHROW { return m_data.m_eyePos; }
-
- inline void setEyeViewDirection(const Vector3D &dir) Q_DECL_NOTHROW { m_data.m_eyeViewDir = dir; }
- inline Vector3D eyeViewDirection() const Q_DECL_NOTHROW { return m_data.m_eyeViewDir; }
-
- inline void appendLayerFilter(const Qt3DCore::QNodeId layerFilterId) Q_DECL_NOTHROW { m_data.m_layerFilterIds.push_back(layerFilterId); }
- inline Qt3DCore::QNodeIdVector layerFilters() const Q_DECL_NOTHROW { return m_data.m_layerFilterIds; }
-
- inline void appendProximityFilterId(const Qt3DCore::QNodeId proximityFilterId) { m_data.m_proximityFilterIds.push_back(proximityFilterId); }
- inline Qt3DCore::QNodeIdVector proximityFilterIds() const { return m_data.m_proximityFilterIds; }
-
- inline void setRenderPassFilter(const RenderPassFilter *rpFilter) Q_DECL_NOTHROW { m_data.m_passFilter = rpFilter; }
- inline const RenderPassFilter *renderPassFilter() const Q_DECL_NOTHROW { return m_data.m_passFilter; }
-
- inline void setTechniqueFilter(const TechniqueFilter *filter) Q_DECL_NOTHROW { m_data.m_techniqueFilter = filter; }
- inline const TechniqueFilter *techniqueFilter() const Q_DECL_NOTHROW { return m_data.m_techniqueFilter; }
-
- inline RenderStateSet *stateSet() const Q_DECL_NOTHROW { return m_stateSet; }
- void setStateSet(RenderStateSet *stateSet) Q_DECL_NOTHROW { m_stateSet = stateSet; }
-
- inline bool noDraw() const Q_DECL_NOTHROW { return m_noDraw; }
- void setNoDraw(bool noDraw) Q_DECL_NOTHROW { m_noDraw = noDraw; }
-
- inline bool isCompute() const Q_DECL_NOTHROW { return m_compute; }
- void setCompute(bool compute) Q_DECL_NOTHROW { m_compute = compute; }
-
- void setComputeWorkgroups(int x, int y, int z) Q_DECL_NOTHROW { m_workGroups[0] = x; m_workGroups[1] = y; m_workGroups[2] = z; }
- const int *computeWorkGroups() const Q_DECL_NOTHROW { return m_workGroups; }
- inline bool frustumCulling() const Q_DECL_NOTHROW { return m_frustumCulling; }
- void setFrustumCulling(bool frustumCulling) Q_DECL_NOTHROW { m_frustumCulling = frustumCulling; }
-
- inline void setMaterialParameterTable(const MaterialParameterGathererData &parameters) Q_DECL_NOTHROW { m_parameters = parameters; }
-
- // TODO: Get rid of this overly complex memory management by splitting out the
- // InnerData as a RenderViewConfig struct. This can be created by setRenderViewConfigFromFrameGraphLeafNode
- // and passed along with the RenderView to the functions that populate the renderview
- inline void setViewport(const QRectF &vp) Q_DECL_NOTHROW { m_viewport = vp; }
- inline QRectF viewport() const Q_DECL_NOTHROW { return m_viewport; }
-
- inline float gamma() const Q_DECL_NOTHROW { return m_gamma; }
- inline void setGamma(float gamma) Q_DECL_NOTHROW { m_gamma = gamma; }
-
- // depth and stencil ClearBuffers are cached locally
- // color ClearBuffers are collected, as there may be multiple
- // color buffers to be cleared. we need to apply all these at rendering
- void addClearBuffers(const ClearBuffers *cb);
- inline QVector<ClearBufferInfo> specificClearColorBufferInfo() const { return m_specificClearColorBuffers; }
- inline QVector<ClearBufferInfo> &specificClearColorBufferInfo() { return m_specificClearColorBuffers; }
- inline ClearBufferInfo globalClearColorBufferInfo() const { return m_globalClearColorBuffer; }
-
- inline QClearBuffers::BufferTypeFlags clearTypes() const { return m_clearBuffer; }
- inline float clearDepthValue() const { return m_clearDepthValue; }
- inline int clearStencilValue() const { return m_clearStencilValue; }
-
- RenderPassList passesAndParameters(ParameterInfoList *parameter, Entity *node, bool useDefaultMaterials = true);
-
- QVector<RenderCommand *> buildDrawRenderCommands(const QVector<Entity *> &entities) const;
- QVector<RenderCommand *> buildComputeRenderCommands(const QVector<Entity *> &entities) const;
- void setCommands(QVector<RenderCommand *> &commands) Q_DECL_NOTHROW { m_commands = commands; }
- QVector<RenderCommand *> commands() const Q_DECL_NOTHROW { return m_commands; }
-
- void setAttachmentPack(const AttachmentPack &pack) { m_attachmentPack = pack; }
- const AttachmentPack &attachmentPack() const { return m_attachmentPack; }
-
- void setRenderTargetId(Qt3DCore::QNodeId renderTargetId) Q_DECL_NOTHROW { m_renderTarget = renderTargetId; }
- Qt3DCore::QNodeId renderTargetId() const Q_DECL_NOTHROW { return m_renderTarget; }
-
- void addSortType(const QVector<Qt3DRender::QSortPolicy::SortType> &sortTypes) { m_data.m_sortingTypes.append(sortTypes); }
-
- void setSurface(QSurface *surface) { m_surface = surface; }
- QSurface *surface() const { return m_surface; }
-
- void setLightSources(const QVector<LightSource> &lightSources) Q_DECL_NOTHROW { m_lightSources = lightSources; }
- void setEnvironmentLight(EnvironmentLight *environmentLight) Q_DECL_NOTHROW { m_environmentLight = environmentLight; }
-
- void updateMatrices();
-
- inline void setRenderCaptureNodeId(const Qt3DCore::QNodeId nodeId) Q_DECL_NOTHROW { m_renderCaptureNodeId = nodeId; }
- inline const Qt3DCore::QNodeId renderCaptureNodeId() const Q_DECL_NOTHROW { return m_renderCaptureNodeId; }
- inline void setRenderCaptureRequest(const QRenderCaptureRequest& request) Q_DECL_NOTHROW { m_renderCaptureRequest = request; }
- inline const QRenderCaptureRequest renderCaptureRequest() const Q_DECL_NOTHROW { return m_renderCaptureRequest; }
-
- void setMemoryBarrier(QMemoryBarrier::Operations barrier) Q_DECL_NOTHROW { m_memoryBarrier = barrier; }
- QMemoryBarrier::Operations memoryBarrier() const Q_DECL_NOTHROW { return m_memoryBarrier; }
-
- // Helps making the size of RenderView smaller
- // Contains all the data needed for the actual building of the RenderView
- // But that aren't used later by the Renderer
- struct InnerData {
- InnerData()
- : m_renderCameraLens(nullptr)
- , m_renderCameraNode(nullptr)
- , m_techniqueFilter(nullptr)
- , m_passFilter(nullptr)
- {
- }
- CameraLens *m_renderCameraLens;
- Entity *m_renderCameraNode;
- const TechniqueFilter *m_techniqueFilter;
- const RenderPassFilter *m_passFilter;
- Matrix4x4 m_viewMatrix;
- Matrix4x4 m_viewProjectionMatrix;
- Qt3DCore::QNodeIdVector m_layerFilterIds;
- QVector<Qt3DRender::QSortPolicy::SortType> m_sortingTypes;
- Vector3D m_eyePos;
- Vector3D m_eyeViewDir;
- Qt3DCore::QNodeIdVector m_proximityFilterIds;
- };
-
- bool isDownloadBuffersEnable() const;
- void setIsDownloadBuffersEnable(bool isDownloadBuffersEnable);
-
- BlitFramebufferInfo blitFrameBufferInfo() const;
- void setBlitFrameBufferInfo(const BlitFramebufferInfo &blitFrameBufferInfo);
-
- bool hasBlitFramebufferInfo() const;
- void setHasBlitFramebufferInfo(bool hasBlitFramebufferInfo);
-
-private:
- void setShaderAndUniforms(RenderCommand *command,
- RenderPass *pass,
- ParameterInfoList &parameters,
- Entity *entity,
- const QVector<LightSource> &activeLightSources,
- EnvironmentLight *environmentLight) const;
- mutable QThreadStorage<UniformBlockValueBuilder*> m_localData;
-
- Qt3DCore::QNodeId m_renderCaptureNodeId;
- QRenderCaptureRequest m_renderCaptureRequest;
- bool m_isDownloadBuffersEnable;
-
- bool m_hasBlitFramebufferInfo;
- BlitFramebufferInfo m_blitFrameBufferInfo;
-
- Renderer *m_renderer;
- NodeManagers *m_manager;
- QSize m_surfaceSize;
- qreal m_devicePixelRatio;
-
- InnerData m_data;
-
- QRectF m_viewport;
- float m_gamma;
- Qt3DCore::QNodeId m_renderTarget;
- QSurface *m_surface;
- AttachmentPack m_attachmentPack;
- QClearBuffers::BufferTypeFlags m_clearBuffer;
- float m_clearDepthValue;
- int m_clearStencilValue;
- ClearBufferInfo m_globalClearColorBuffer; // global ClearColor
- QVector<ClearBufferInfo> m_specificClearColorBuffers; // different draw buffers with distinct colors
- RenderStateSet *m_stateSet;
- bool m_noDraw:1;
- bool m_compute:1;
- bool m_frustumCulling:1;
- int m_workGroups[3];
- QMemoryBarrier::Operations m_memoryBarrier;
-
- // We do not use pointers to RenderNodes or Drawable's here so that the
- // render aspect is free to change the drawables on the next frame whilst
- // the render thread is submitting these commands.
- QVector<RenderCommand *> m_commands;
- mutable QVector<LightSource> m_lightSources;
- EnvironmentLight *m_environmentLight;
-
- MaterialParameterGathererData m_parameters;
-
- enum StandardUniform
- {
- ModelMatrix,
- ViewMatrix,
- ProjectionMatrix,
- ModelViewMatrix,
- ViewProjectionMatrix,
- ModelViewProjectionMatrix,
- InverseModelMatrix,
- InverseViewMatrix,
- InverseProjectionMatrix,
- InverseModelViewMatrix,
- InverseViewProjectionMatrix,
- InverseModelViewProjectionMatrix,
- ModelNormalMatrix,
- ModelViewNormalMatrix,
- ViewportMatrix,
- InverseViewportMatrix,
- AspectRatio,
- Time,
- Exposure,
- Gamma,
- EyePosition,
- SkinningPalette
- };
-
- typedef QHash<int, StandardUniform> StandardUniformsNameToTypeHash;
- static StandardUniformsNameToTypeHash ms_standardUniformSetters;
- static StandardUniformsNameToTypeHash initializeStandardUniformSetters();
-
- UniformValue standardUniformValue(StandardUniform standardUniformType,
- Entity *entity,
- const Matrix4x4 &model) const;
-
- void setUniformValue(ShaderParameterPack &uniformPack, int nameId, const UniformValue &value) const;
- void setStandardUniformValue(ShaderParameterPack &uniformPack,
- int glslNameId,
- int nameId,
- Entity *entity,
- const Matrix4x4 &worldTransform) const;
- void setUniformBlockValue(ShaderParameterPack &uniformPack,
- Shader *shader,
- const ShaderUniformBlock &block,
- const UniformValue &value) const;
- void setShaderStorageValue(ShaderParameterPack &uniformPack,
- Shader *shader,
- const ShaderStorageBlock &block,
- const UniformValue &value) const;
- void setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack,
- Shader *shader,
- ShaderData *shaderData,
- const QString &structName) const;
-};
-
-} // namespace Render
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
-
-#endif // QT3DRENDER_RENDER_RENDERVIEW_H
diff --git a/src/render/backend/renderviewbuilder.cpp b/src/render/backend/renderviewbuilder.cpp
deleted file mode 100644
index d08bd6dd4..000000000
--- a/src/render/backend/renderviewbuilder.cpp
+++ /dev/null
@@ -1,672 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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$
-**
-****************************************************************************/
-
-#include "renderviewbuilder_p.h"
-
-#include <QThread>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-
-namespace Render {
-
-const int RenderViewBuilder::m_optimalParallelJobCount = std::max(QThread::idealThreadCount(), 2);
-
-namespace {
-
-class SyncRenderViewCommandBuilders
-{
-public:
- explicit SyncRenderViewCommandBuilders(const RenderViewInitializerJobPtr &renderViewJob,
- const QVector<RenderViewBuilderJobPtr> &renderViewBuilderJobs,
- Renderer *renderer)
- : m_renderViewJob(renderViewJob)
- , m_renderViewBuilderJobs(renderViewBuilderJobs)
- , m_renderer(renderer)
- {}
-
- void operator()()
- {
- // Append all the commands and sort them
- RenderView *rv = m_renderViewJob->renderView();
-
- int totalCommandCount = 0;
- for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs))
- totalCommandCount += renderViewCommandBuilder->commands().size();
-
- QVector<RenderCommand *> commands;
- commands.reserve(totalCommandCount);
-
- // Reduction
- for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs))
- commands += std::move(renderViewCommandBuilder->commands());
- rv->setCommands(commands);
-
- // Sort the commands
- rv->sort();
-
- // Enqueue our fully populated RenderView with the RenderThread
- m_renderer->enqueueRenderView(rv, m_renderViewJob->submitOrderIndex());
- }
-
-private:
- RenderViewInitializerJobPtr m_renderViewJob;
- QVector<RenderViewBuilderJobPtr> m_renderViewBuilderJobs;
- Renderer *m_renderer;
-};
-
-class SyncFrustumCulling
-{
-public:
- explicit SyncFrustumCulling(const RenderViewInitializerJobPtr &renderViewJob,
- const FrustumCullingJobPtr &frustumCulling)
- : m_renderViewJob(renderViewJob)
- , m_frustumCullingJob(frustumCulling)
- {}
-
- void operator()()
- {
- RenderView *rv = m_renderViewJob->renderView();
-
- // Update matrices now that all transforms have been updated
- rv->updateMatrices();
-
- // Frustum culling
- m_frustumCullingJob->setViewProjection(rv->viewProjectionMatrix());
- }
-
-private:
- RenderViewInitializerJobPtr m_renderViewJob;
- FrustumCullingJobPtr m_frustumCullingJob;
-};
-
-class SyncRenderViewInitialization
-{
-public:
- explicit SyncRenderViewInitialization(const RenderViewInitializerJobPtr &renderViewJob,
- const FrustumCullingJobPtr &frustumCullingJob,
- const FilterLayerEntityJobPtr &filterEntityByLayerJob,
- const FilterProximityDistanceJobPtr &filterProximityJob,
- const QVector<MaterialParameterGathererJobPtr> &materialGathererJobs,
- const QVector<RenderViewBuilderJobPtr> &renderViewBuilderJobs)
- : m_renderViewJob(renderViewJob)
- , m_frustumCullingJob(frustumCullingJob)
- , m_filterEntityByLayerJob(filterEntityByLayerJob)
- , m_filterProximityJob(filterProximityJob)
- , m_materialGathererJobs(materialGathererJobs)
- , m_renderViewBuilderJobs(renderViewBuilderJobs)
- {}
-
- void operator()()
- {
- RenderView *rv = m_renderViewJob->renderView();
-
- // Layer filtering
- if (!m_filterEntityByLayerJob.isNull())
- m_filterEntityByLayerJob->setLayerFilters(rv->layerFilters());
-
- // Proximity filtering
- m_filterProximityJob->setProximityFilterIds(rv->proximityFilterIds());
-
- // Material Parameter building
- for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) {
- materialGatherer->setRenderPassFilter(const_cast<RenderPassFilter *>(rv->renderPassFilter()));
- materialGatherer->setTechniqueFilter(const_cast<TechniqueFilter *>(rv->techniqueFilter()));
- }
-
- // Command builders
- for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs))
- renderViewCommandBuilder->setRenderView(rv);
-
- // Set whether frustum culling is enabled or not
- m_frustumCullingJob->setActive(rv->frustumCulling());
- }
-
-private:
- RenderViewInitializerJobPtr m_renderViewJob;
- FrustumCullingJobPtr m_frustumCullingJob;
- FilterLayerEntityJobPtr m_filterEntityByLayerJob;
- FilterProximityDistanceJobPtr m_filterProximityJob;
- QVector<MaterialParameterGathererJobPtr> m_materialGathererJobs;
- QVector<RenderViewBuilderJobPtr> m_renderViewBuilderJobs;
-};
-
-class SyncRenderCommandBuilding
-{
-public:
- explicit SyncRenderCommandBuilding(const RenderViewInitializerJobPtr &renderViewJob,
- const FrustumCullingJobPtr &frustumCullingJob,
- const FilterProximityDistanceJobPtr &filterProximityJob,
- const LightGathererPtr &lightGathererJob,
- const RenderableEntityFilterPtr &renderableEntityFilterJob,
- const ComputableEntityFilterPtr &computableEntityFilterJob,
- const QVector<MaterialParameterGathererJobPtr> &materialGathererJobs,
- const QVector<RenderViewBuilderJobPtr> &renderViewBuilderJobs,
- Renderer *renderer,
- FrameGraphNode *leafNode)
- : m_renderViewJob(renderViewJob)
- , m_frustumCullingJob(frustumCullingJob)
- , m_filterProximityJob(filterProximityJob)
- , m_lightGathererJob(lightGathererJob)
- , m_renderableEntityFilterJob(renderableEntityFilterJob)
- , m_computableEntityFilterJob(computableEntityFilterJob)
- , m_materialGathererJobs(materialGathererJobs)
- , m_renderViewBuilderJobs(renderViewBuilderJobs)
- , m_renderer(renderer)
- , m_leafNode(leafNode)
- {}
-
- void operator()()
- {
- // Set the result of previous job computations
- // for final RenderCommand building
- RenderView *rv = m_renderViewJob->renderView();
-
- if (!rv->noDraw()) {
- rv->setEnvironmentLight(m_lightGathererJob->takeEnvironmentLight());
-
- // We sort the vector so that the removal can then be performed linearly
-
- QVector<Entity *> renderableEntities;
- const bool isDraw = !rv->isCompute();
- if (isDraw)
- renderableEntities = std::move(m_renderableEntityFilterJob->filteredEntities());
- else
- renderableEntities = std::move(m_computableEntityFilterJob->filteredEntities());
-
- // Filter out entities that weren't selected by the layer filters
- std::sort(renderableEntities.begin(), renderableEntities.end());
-
- QMutexLocker lock(m_renderer->cache()->mutex());
- const QVector<Entity *> filteredEntities = m_renderer->cache()->leafNodeCache.value(m_leafNode).filterEntitiesByLayer;
- lock.unlock();
- // Remove all entities from the compute and renderable vectors that aren't in the filtered layer vector
- renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, filteredEntities);
-
- // Set the light sources, with layer filters applied.
- QVector<LightSource> lightSources = m_lightGathererJob->lights();
- for (int i = 0; i < lightSources.count(); ++i) {
- if (!filteredEntities.contains(lightSources[i].entity))
- lightSources.removeAt(i--);
- }
- rv->setLightSources(lightSources);
-
- if (isDraw) {
- // Filter out frustum culled entity for drawable entities
- if (rv->frustumCulling())
- renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, m_frustumCullingJob->visibleEntities());
- // Filter out entities which didn't satisfy proximity filtering
- renderableEntities = RenderViewBuilder::entitiesInSubset(renderableEntities, m_filterProximityJob->filteredEntities());
- }
-
- // Split among the number of command builders
- int i = 0;
- const int m = RenderViewBuilder::optimalJobCount() - 1;
- const int packetSize = renderableEntities.size() / RenderViewBuilder::optimalJobCount();
- while (i < m) {
- const RenderViewBuilderJobPtr renderViewCommandBuilder = m_renderViewBuilderJobs.at(i);
- renderViewCommandBuilder->setRenderables(renderableEntities.mid(i * packetSize, packetSize));
- ++i;
- }
- m_renderViewBuilderJobs.at(i)->setRenderables(renderableEntities.mid(i * packetSize, packetSize + renderableEntities.size() % (m + 1)));
- {
- QMutexLocker rendererCacheLock(m_renderer->cache()->mutex());
- rv->setMaterialParameterTable(m_renderer->cache()->leafNodeCache.value(m_leafNode).materialParameterGatherer);
- }
- }
- }
-
-private:
- RenderViewInitializerJobPtr m_renderViewJob;
- FrustumCullingJobPtr m_frustumCullingJob;
- FilterProximityDistanceJobPtr m_filterProximityJob;
- LightGathererPtr m_lightGathererJob;
- RenderableEntityFilterPtr m_renderableEntityFilterJob;
- ComputableEntityFilterPtr m_computableEntityFilterJob;
- QVector<MaterialParameterGathererJobPtr> m_materialGathererJobs;
- QVector<RenderViewBuilderJobPtr> m_renderViewBuilderJobs;
- Renderer *m_renderer;
- FrameGraphNode *m_leafNode;
-};
-
-class SetClearDrawBufferIndex
-{
-public:
- explicit SetClearDrawBufferIndex(const RenderViewInitializerJobPtr &renderViewJob)
- : m_renderViewJob(renderViewJob)
- {}
-
- void operator()()
- {
- RenderView *rv = m_renderViewJob->renderView();
- QVector<ClearBufferInfo> &clearBuffersInfo = rv->specificClearColorBufferInfo();
- const AttachmentPack &attachmentPack = rv->attachmentPack();
- for (ClearBufferInfo &clearBufferInfo : clearBuffersInfo)
- clearBufferInfo.drawBufferIndex = attachmentPack.getDrawBufferIndex(clearBufferInfo.attchmentPoint);
-
- }
-
-private:
- RenderViewInitializerJobPtr m_renderViewJob;
-};
-
-class SyncFilterEntityByLayer
-{
-public:
- explicit SyncFilterEntityByLayer(const FilterLayerEntityJobPtr &filterEntityByLayerJob,
- Renderer *renderer,
- FrameGraphNode *leafNode)
- : m_filterEntityByLayerJob(filterEntityByLayerJob)
- , m_renderer(renderer)
- , m_leafNode(leafNode)
- {
- }
-
- void operator()()
- {
- QMutexLocker lock(m_renderer->cache()->mutex());
- // Save the filtered by layer subset into the cache
- const QVector<Entity *> filteredEntities = m_filterEntityByLayerJob->filteredEntities();
- RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode];
- dataCacheForLeaf.filterEntitiesByLayer = filteredEntities;
- }
-
-private:
- FilterLayerEntityJobPtr m_filterEntityByLayerJob;
- Renderer *m_renderer;
- FrameGraphNode *m_leafNode;
-};
-
-class SyncMaterialParameterGatherer
-{
-public:
- explicit SyncMaterialParameterGatherer(const QVector<MaterialParameterGathererJobPtr> &materialParameterGathererJobs,
- Renderer *renderer,
- FrameGraphNode *leafNode)
- : m_materialParameterGathererJobs(materialParameterGathererJobs)
- , m_renderer(renderer)
- , m_leafNode(leafNode)
- {
- }
-
- void operator()()
- {
- QMutexLocker lock(m_renderer->cache()->mutex());
- RendererCache::LeafNodeData &dataCacheForLeaf = m_renderer->cache()->leafNodeCache[m_leafNode];
- dataCacheForLeaf.materialParameterGatherer.clear();
-
- for (const auto &materialGatherer : qAsConst(m_materialParameterGathererJobs))
- dataCacheForLeaf.materialParameterGatherer.unite(materialGatherer->materialToPassAndParameter());
- }
-
-private:
- QVector<MaterialParameterGathererJobPtr> m_materialParameterGathererJobs;
- Renderer *m_renderer;
- FrameGraphNode *m_leafNode;
-};
-
-} // anonymous
-
-RenderViewBuilder::RenderViewBuilder(Render::FrameGraphNode *leafNode, int renderViewIndex, Renderer *renderer)
- : m_leafNode(leafNode)
- , m_renderViewIndex(renderViewIndex)
- , m_renderer(renderer)
- , m_layerCacheNeedsToBeRebuilt(false)
- , m_materialGathererCacheNeedsToBeRebuilt(false)
- , m_renderViewJob(RenderViewInitializerJobPtr::create())
- , m_filterEntityByLayerJob()
- , m_lightGathererJob(Render::LightGathererPtr::create())
- , m_renderableEntityFilterJob(RenderableEntityFilterPtr::create())
- , m_computableEntityFilterJob(ComputableEntityFilterPtr::create())
- , m_frustumCullingJob(new Render::FrustumCullingJob())
- , m_syncFrustumCullingJob(SynchronizerJobPtr::create(SyncFrustumCulling(m_renderViewJob, m_frustumCullingJob), JobTypes::SyncFrustumCulling))
- , m_setClearDrawBufferIndexJob(SynchronizerJobPtr::create(SetClearDrawBufferIndex(m_renderViewJob), JobTypes::ClearBufferDrawIndex))
- , m_syncFilterEntityByLayerJob()
- , m_filterProximityJob(Render::FilterProximityDistanceJobPtr::create())
-{
-}
-
-RenderViewInitializerJobPtr RenderViewBuilder::renderViewJob() const
-{
- return m_renderViewJob;
-}
-
-FilterLayerEntityJobPtr RenderViewBuilder::filterEntityByLayerJob() const
-{
- return m_filterEntityByLayerJob;
-}
-
-LightGathererPtr RenderViewBuilder::lightGathererJob() const
-{
- return m_lightGathererJob;
-}
-
-RenderableEntityFilterPtr RenderViewBuilder::renderableEntityFilterJob() const
-{
- return m_renderableEntityFilterJob;
-}
-
-ComputableEntityFilterPtr RenderViewBuilder::computableEntityFilterJob() const
-{
- return m_computableEntityFilterJob;
-}
-
-FrustumCullingJobPtr RenderViewBuilder::frustumCullingJob() const
-{
- return m_frustumCullingJob;
-}
-
-QVector<RenderViewBuilderJobPtr> RenderViewBuilder::renderViewBuilderJobs() const
-{
- return m_renderViewBuilderJobs;
-}
-
-QVector<MaterialParameterGathererJobPtr> RenderViewBuilder::materialGathererJobs() const
-{
- return m_materialGathererJobs;
-}
-
-SynchronizerJobPtr RenderViewBuilder::syncRenderViewInitializationJob() const
-{
- return m_syncRenderViewInitializationJob;
-}
-
-SynchronizerJobPtr RenderViewBuilder::syncFrustumCullingJob() const
-{
- return m_syncFrustumCullingJob;
-}
-
-SynchronizerJobPtr RenderViewBuilder::syncRenderCommandBuildingJob() const
-{
- return m_syncRenderCommandBuildingJob;
-}
-
-SynchronizerJobPtr RenderViewBuilder::syncRenderViewCommandBuildersJob() const
-{
- return m_syncRenderViewCommandBuildersJob;
-}
-
-SynchronizerJobPtr RenderViewBuilder::setClearDrawBufferIndexJob() const
-{
- return m_setClearDrawBufferIndexJob;
-}
-
-SynchronizerJobPtr RenderViewBuilder::syncFilterEntityByLayerJob() const
-{
- return m_syncFilterEntityByLayerJob;
-}
-
-SynchronizerJobPtr RenderViewBuilder::syncMaterialGathererJob() const
-{
- return m_syncMaterialGathererJob;
-}
-
-FilterProximityDistanceJobPtr RenderViewBuilder::filterProximityJob() const
-{
- return m_filterProximityJob;
-}
-
-void RenderViewBuilder::prepareJobs()
-{
- // Init what we can here
- EntityManager *entityManager = m_renderer->nodeManagers()->renderNodesManager();
- m_filterProximityJob->setManager(m_renderer->nodeManagers());
- m_renderableEntityFilterJob->setManager(entityManager);
- m_computableEntityFilterJob->setManager(entityManager);
- m_frustumCullingJob->setRoot(m_renderer->sceneRoot());
- m_lightGathererJob->setManager(entityManager);
- m_renderViewJob->setRenderer(m_renderer);
- m_renderViewJob->setFrameGraphLeafNode(m_leafNode);
- m_renderViewJob->setSubmitOrderIndex(m_renderViewIndex);
-
- // RenderCommand building is the most consuming task -> split it
- // Estimate the number of jobs to create based on the number of entities
- m_renderViewBuilderJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount);
- for (auto i = 0; i < RenderViewBuilder::m_optimalParallelJobCount; ++i) {
- auto renderViewCommandBuilder = Render::RenderViewBuilderJobPtr::create();
- renderViewCommandBuilder->setIndex(m_renderViewIndex);
- renderViewCommandBuilder->setRenderer(m_renderer);
- m_renderViewBuilderJobs.push_back(renderViewCommandBuilder);
- }
-
- if (m_materialGathererCacheNeedsToBeRebuilt) {
- // Since Material gathering is an heavy task, we split it
- const QVector<HMaterial> materialHandles = m_renderer->nodeManagers()->materialManager()->activeHandles();
- const int elementsPerJob = materialHandles.size() / RenderViewBuilder::m_optimalParallelJobCount;
- const int lastRemaingElements = materialHandles.size() % RenderViewBuilder::m_optimalParallelJobCount;
- m_materialGathererJobs.reserve(RenderViewBuilder::m_optimalParallelJobCount);
- for (auto i = 0; i < RenderViewBuilder::m_optimalParallelJobCount; ++i) {
- auto materialGatherer = Render::MaterialParameterGathererJobPtr::create();
- materialGatherer->setNodeManagers(m_renderer->nodeManagers());
- materialGatherer->setRenderer(m_renderer);
- if (i == RenderViewBuilder::m_optimalParallelJobCount - 1)
- materialGatherer->setHandles(materialHandles.mid(i * elementsPerJob, elementsPerJob + lastRemaingElements));
- else
- materialGatherer->setHandles(materialHandles.mid(i * elementsPerJob, elementsPerJob));
- m_materialGathererJobs.push_back(materialGatherer);
- }
- m_syncMaterialGathererJob = SynchronizerJobPtr::create(SyncMaterialParameterGatherer(m_materialGathererJobs,
- m_renderer,
- m_leafNode),
- JobTypes::SyncMaterialGatherer);
- }
-
- if (m_layerCacheNeedsToBeRebuilt) {
- m_filterEntityByLayerJob = Render::FilterLayerEntityJobPtr::create();
- m_filterEntityByLayerJob->setManager(m_renderer->nodeManagers());
- m_syncFilterEntityByLayerJob = SynchronizerJobPtr::create(SyncFilterEntityByLayer(m_filterEntityByLayerJob,
- m_renderer,
- m_leafNode),
- JobTypes::SyncFilterEntityByLayer);
- }
-
- m_syncRenderCommandBuildingJob = SynchronizerJobPtr::create(SyncRenderCommandBuilding(m_renderViewJob,
- m_frustumCullingJob,
- m_filterProximityJob,
- m_lightGathererJob,
- m_renderableEntityFilterJob,
- m_computableEntityFilterJob,
- m_materialGathererJobs,
- m_renderViewBuilderJobs,
- m_renderer,
- m_leafNode),
- JobTypes::SyncRenderViewCommandBuilding);
-
- m_syncRenderViewCommandBuildersJob = SynchronizerJobPtr::create(SyncRenderViewCommandBuilders(m_renderViewJob,
- m_renderViewBuilderJobs,
- m_renderer),
- JobTypes::SyncRenderViewCommandBuilder);
-
- m_syncRenderViewInitializationJob = SynchronizerJobPtr::create(SyncRenderViewInitialization(m_renderViewJob,
- m_frustumCullingJob,
- m_filterEntityByLayerJob,
- m_filterProximityJob,
- m_materialGathererJobs,
- m_renderViewBuilderJobs),
- JobTypes::SyncRenderViewInitialization);
-
-}
-
-QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
-{
- QVector<Qt3DCore::QAspectJobPtr> jobs;
-
- jobs.reserve(m_materialGathererJobs.size() + m_renderViewBuilderJobs.size() + 11);
-
- // Set dependencies
-
- // Finish the skinning palette job before processing renderviews
- // TODO: Maybe only update skinning palettes for non-culled entities
- m_renderViewJob->addDependency(m_renderer->updateSkinningPaletteJob());
-
- m_syncFrustumCullingJob->addDependency(m_renderer->updateWorldTransformJob());
- m_syncFrustumCullingJob->addDependency(m_renderer->updateShaderDataTransformJob());
- m_syncFrustumCullingJob->addDependency(m_syncRenderViewInitializationJob);
-
- m_frustumCullingJob->addDependency(m_renderer->expandBoundingVolumeJob());
- m_frustumCullingJob->addDependency(m_syncFrustumCullingJob);
-
- m_setClearDrawBufferIndexJob->addDependency(m_syncRenderViewInitializationJob);
-
- m_syncRenderViewInitializationJob->addDependency(m_renderViewJob);
-
- m_filterProximityJob->addDependency(m_renderer->expandBoundingVolumeJob());
- m_filterProximityJob->addDependency(m_syncRenderViewInitializationJob);
-
- m_syncRenderCommandBuildingJob->addDependency(m_syncRenderViewInitializationJob);
- m_syncRenderCommandBuildingJob->addDependency(m_renderableEntityFilterJob);
- m_syncRenderCommandBuildingJob->addDependency(m_computableEntityFilterJob);
- m_syncRenderCommandBuildingJob->addDependency(m_filterProximityJob);
- m_syncRenderCommandBuildingJob->addDependency(m_lightGathererJob);
- m_syncRenderCommandBuildingJob->addDependency(m_frustumCullingJob);
-
- // Ensure the RenderThread won't be able to process dirtyResources
- // before they have been completely gathered
- m_syncRenderCommandBuildingJob->addDependency(m_renderer->introspectShadersJob());
- m_syncRenderCommandBuildingJob->addDependency(m_renderer->bufferGathererJob());
- m_syncRenderCommandBuildingJob->addDependency(m_renderer->textureGathererJob());
-
- for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) {
- renderViewCommandBuilder->addDependency(m_syncRenderCommandBuildingJob);
- m_syncRenderViewCommandBuildersJob->addDependency(renderViewCommandBuilder);
- }
-
- m_renderer->frameCleanupJob()->addDependency(m_syncRenderViewCommandBuildersJob);
- m_renderer->frameCleanupJob()->addDependency(m_setClearDrawBufferIndexJob);
-
- // Add jobs
- jobs.push_back(m_renderViewJob); // Step 1
- jobs.push_back(m_renderableEntityFilterJob); // Step 1
- jobs.push_back(m_lightGathererJob); // Step 1
-
- // Note: do it only if OpenGL 4.3+ available
- jobs.push_back(m_computableEntityFilterJob); // Step 1
-
- jobs.push_back(m_syncRenderViewInitializationJob); // Step 2
-
- if (m_layerCacheNeedsToBeRebuilt) {
- m_filterEntityByLayerJob->addDependency(m_syncRenderViewInitializationJob);
- m_filterEntityByLayerJob->addDependency(m_renderer->updateTreeEnabledJob());
-
- m_syncFilterEntityByLayerJob->addDependency(m_filterEntityByLayerJob);
- m_syncRenderCommandBuildingJob->addDependency(m_syncFilterEntityByLayerJob);
-
- jobs.push_back(m_filterEntityByLayerJob); // Step 3
- jobs.push_back(m_syncFilterEntityByLayerJob); // Step 4
- }
- jobs.push_back(m_syncFrustumCullingJob); // Step 3
- jobs.push_back(m_filterProximityJob); // Step 3
- jobs.push_back(m_setClearDrawBufferIndexJob); // Step 3
-
- if (m_materialGathererCacheNeedsToBeRebuilt) {
- for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) {
- materialGatherer->addDependency(m_syncRenderViewInitializationJob);
- materialGatherer->addDependency(m_renderer->introspectShadersJob());
- materialGatherer->addDependency(m_renderer->filterCompatibleTechniqueJob());
- jobs.push_back(materialGatherer); // Step3
- m_syncMaterialGathererJob->addDependency(materialGatherer);
- }
- m_syncRenderCommandBuildingJob->addDependency(m_syncMaterialGathererJob);
-
- jobs.push_back(m_syncMaterialGathererJob); // Step 3
- }
-
- jobs.push_back(m_frustumCullingJob); // Step 4
- jobs.push_back(m_syncRenderCommandBuildingJob); // Step 5
-
- for (const auto &renderViewCommandBuilder : qAsConst(m_renderViewBuilderJobs)) // Step 6
- jobs.push_back(renderViewCommandBuilder);
-
- jobs.push_back(m_syncRenderViewCommandBuildersJob); // Step 7
-
- return jobs;
-}
-
-Renderer *RenderViewBuilder::renderer() const
-{
- return m_renderer;
-}
-
-int RenderViewBuilder::renderViewIndex() const
-{
- return m_renderViewIndex;
-}
-
-void RenderViewBuilder::setLayerCacheNeedsToBeRebuilt(bool needsToBeRebuilt)
-{
- m_layerCacheNeedsToBeRebuilt = needsToBeRebuilt;
-}
-
-bool RenderViewBuilder::layerCacheNeedsToBeRebuilt() const
-{
- return m_layerCacheNeedsToBeRebuilt;
-}
-
-void RenderViewBuilder::setMaterialGathererCacheNeedsToBeRebuilt(bool needsToBeRebuilt)
-{
- m_materialGathererCacheNeedsToBeRebuilt = needsToBeRebuilt;
-}
-
-bool RenderViewBuilder::materialGathererCacheNeedsToBeRebuilt() const
-{
- return m_materialGathererCacheNeedsToBeRebuilt;
-}
-
-int RenderViewBuilder::optimalJobCount()
-{
- return RenderViewBuilder::m_optimalParallelJobCount;
-}
-
-QVector<Entity *> RenderViewBuilder::entitiesInSubset(const QVector<Entity *> &entities, const QVector<Entity *> &subset)
-{
- QVector<Entity *> intersection;
- intersection.reserve(qMin(entities.size(), subset.size()));
- std::set_intersection(entities.begin(), entities.end(),
- subset.begin(), subset.end(),
- std::back_inserter(intersection));
-
- return intersection;
-}
-
-} // Render
-
-} // Qt3DRender
-
-QT_END_NAMESPACE
diff --git a/src/render/backend/renderviewbuilder_p.h b/src/render/backend/renderviewbuilder_p.h
deleted file mode 100644
index 818313500..000000000
--- a/src/render/backend/renderviewbuilder_p.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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 QT3DRENDER_RENDER_RENDERVIEWBUILDER_H
-#define QT3DRENDER_RENDER_RENDERVIEWBUILDER_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 <functional>
-#include <Qt3DCore/qaspectjob.h>
-#include <Qt3DRender/private/filterentitybycomponentjob_p.h>
-#include <Qt3DRender/private/filterlayerentityjob_p.h>
-#include <Qt3DRender/private/genericlambdajob_p.h>
-#include <Qt3DRender/private/materialparametergathererjob_p.h>
-#include <Qt3DRender/private/nodemanagers_p.h>
-#include <Qt3DRender/private/renderviewbuilderjob_p.h>
-#include <Qt3DRender/private/renderview_p.h>
-#include <Qt3DRender/private/frustumcullingjob_p.h>
-#include <Qt3DRender/private/lightgatherer_p.h>
-#include <Qt3DRender/private/filterproximitydistancejob_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-
-namespace Render {
-
-class Renderer;
-
-using SynchronizerJobPtr = GenericLambdaJobPtr<std::function<void()>>;
-using ComputableEntityFilterPtr = FilterEntityByComponentJobPtr<Render::ComputeCommand, Render::Material>;
-using RenderableEntityFilterPtr = FilterEntityByComponentJobPtr<Render::GeometryRenderer, Render::Material>;
-
-class Q_AUTOTEST_EXPORT RenderViewBuilder
-{
-public:
- explicit RenderViewBuilder(Render::FrameGraphNode *leafNode, int renderViewIndex, Renderer *renderer);
-
- RenderViewInitializerJobPtr renderViewJob() const;
- FilterLayerEntityJobPtr filterEntityByLayerJob() const;
- LightGathererPtr lightGathererJob() const;
- RenderableEntityFilterPtr renderableEntityFilterJob() const;
- ComputableEntityFilterPtr computableEntityFilterJob() const;
- FrustumCullingJobPtr frustumCullingJob() const;
- QVector<RenderViewBuilderJobPtr> renderViewBuilderJobs() const;
- QVector<MaterialParameterGathererJobPtr> materialGathererJobs() const;
- SynchronizerJobPtr syncRenderViewInitializationJob() const;
- SynchronizerJobPtr syncFrustumCullingJob() const;
- SynchronizerJobPtr syncRenderCommandBuildingJob() const;
- SynchronizerJobPtr syncRenderViewCommandBuildersJob() const;
- SynchronizerJobPtr setClearDrawBufferIndexJob() const;
- SynchronizerJobPtr syncFilterEntityByLayerJob() const;
- FilterProximityDistanceJobPtr filterProximityJob() const;
- SynchronizerJobPtr syncMaterialGathererJob() const;
-
- void prepareJobs();
- QVector<Qt3DCore::QAspectJobPtr> buildJobHierachy() const;
-
- Renderer *renderer() const;
- int renderViewIndex() const;
-
- void setLayerCacheNeedsToBeRebuilt(bool needsToBeRebuilt);
- bool layerCacheNeedsToBeRebuilt() const;
- void setMaterialGathererCacheNeedsToBeRebuilt(bool needsToBeRebuilt);
- bool materialGathererCacheNeedsToBeRebuilt() const;
-
- static int optimalJobCount();
- static QVector<Entity *> entitiesInSubset(const QVector<Entity *> &entities, const QVector<Entity *> &subset);
-
-private:
- Render::FrameGraphNode *m_leafNode;
- const int m_renderViewIndex;
- Renderer *m_renderer;
- bool m_layerCacheNeedsToBeRebuilt;
- bool m_materialGathererCacheNeedsToBeRebuilt;
-
- RenderViewInitializerJobPtr m_renderViewJob;
- FilterLayerEntityJobPtr m_filterEntityByLayerJob;
- LightGathererPtr m_lightGathererJob;
- RenderableEntityFilterPtr m_renderableEntityFilterJob;
- ComputableEntityFilterPtr m_computableEntityFilterJob;
- FrustumCullingJobPtr m_frustumCullingJob;
- QVector<RenderViewBuilderJobPtr> m_renderViewBuilderJobs;
- QVector<MaterialParameterGathererJobPtr> m_materialGathererJobs;
-
- SynchronizerJobPtr m_syncRenderViewInitializationJob;
- SynchronizerJobPtr m_syncFrustumCullingJob;
- SynchronizerJobPtr m_syncRenderCommandBuildingJob;
- SynchronizerJobPtr m_syncRenderViewCommandBuildersJob;
- SynchronizerJobPtr m_setClearDrawBufferIndexJob;
- SynchronizerJobPtr m_syncFilterEntityByLayerJob;
- SynchronizerJobPtr m_syncMaterialGathererJob;
- FilterProximityDistanceJobPtr m_filterProximityJob;
-
- static const int m_optimalParallelJobCount;
-};
-
-} // Render
-
-} // Qt3DRender
-
-QT_END_NAMESPACE
-
-#endif // QT3DRENDER_RENDER_RENDERVIEWBUILDER_H
diff --git a/src/render/backend/shaderparameterpack.cpp b/src/render/backend/shaderparameterpack.cpp
deleted file mode 100644
index f78e45a5e..000000000
--- a/src/render/backend/shaderparameterpack.cpp
+++ /dev/null
@@ -1,100 +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$
-**
-****************************************************************************/
-
-#include "shaderparameterpack_p.h"
-
-#include <Qt3DRender/private/graphicscontext_p.h>
-#include <Qt3DRender/private/texture_p.h>
-
-#include <Qt3DCore/private/qframeallocator_p.h>
-
-#include <QOpenGLShaderProgram>
-#include <QDebug>
-#include <QColor>
-#include <QQuaternion>
-#include <Qt3DRender/private/renderlogging_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-namespace Render {
-
-ShaderParameterPack::~ShaderParameterPack()
-{
- m_uniforms.clear();
-}
-
-void ShaderParameterPack::setUniform(const int glslNameId, const UniformValue &val)
-{
- m_uniforms.insert(glslNameId, val);
-}
-
-void ShaderParameterPack::setTexture(const int glslNameId, int uniformArrayIndex, Qt3DCore::QNodeId texId)
-{
- for (int t=0; t<m_textures.size(); ++t) {
- if (m_textures[t].glslNameId != glslNameId || m_textures[t].uniformArrayIndex != uniformArrayIndex)
- continue;
-
- m_textures[t].texId = texId;
- return;
- }
-
- m_textures.append(NamedTexture(glslNameId, texId, uniformArrayIndex));
-}
-
-// Contains Uniform Block Index and QNodeId of the ShaderData (UBO)
-void ShaderParameterPack::setUniformBuffer(BlockToUBO blockToUBO)
-{
- m_uniformBuffers.append(std::move(blockToUBO));
-}
-
-void ShaderParameterPack::setShaderStorageBuffer(BlockToSSBO blockToSSBO)
-{
- m_shaderStorageBuffers.push_back(std::move(blockToSSBO));
-}
-
-void ShaderParameterPack::setSubmissionUniform(const ShaderUniform &uniform)
-{
- m_submissionUniforms.push_back(uniform);
-}
-
-} // namespace Render
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
diff --git a/src/render/backend/shaderparameterpack_p.h b/src/render/backend/shaderparameterpack_p.h
deleted file mode 100644
index 5703bb17b..000000000
--- a/src/render/backend/shaderparameterpack_p.h
+++ /dev/null
@@ -1,145 +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 QT3DRENDER_RENDER_SHADERPARAMETERPACK_P_H
-#define QT3DRENDER_RENDER_SHADERPARAMETERPACK_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 <QVariant>
-#include <QByteArray>
-#include <QVector>
-#include <QOpenGLShaderProgram>
-#include <Qt3DCore/qnodeid.h>
-#include <Qt3DRender/private/renderlogging_p.h>
-#include <Qt3DRender/private/shadervariables_p.h>
-#include <Qt3DRender/private/uniform_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QOpenGLShaderProgram;
-
-namespace Qt3DCore {
-class QFrameAllocator;
-}
-
-namespace Qt3DRender {
-namespace Render {
-
-class GraphicsContext;
-
-struct BlockToUBO {
- int m_blockIndex;
- Qt3DCore::QNodeId m_bufferID;
- bool m_needsUpdate;
- QHash<QString, QVariant> m_updatedProperties;
-};
-QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, BlockToUBO, Q_MOVABLE_TYPE)
-
-struct BlockToSSBO {
- int m_blockIndex;
- Qt3DCore::QNodeId m_bufferID;
-};
-QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, BlockToSSBO, Q_PRIMITIVE_TYPE)
-
-
-typedef QHash<int, UniformValue> PackUniformHash;
-
-class Q_AUTOTEST_EXPORT ShaderParameterPack
-{
-public:
- ~ShaderParameterPack();
-
- void setUniform(const int glslNameId, const UniformValue &val);
- void setTexture(const int glslNameId, int uniformArrayIndex, Qt3DCore::QNodeId id);
- void setUniformBuffer(BlockToUBO blockToUBO);
- void setShaderStorageBuffer(BlockToSSBO blockToSSBO);
- void setSubmissionUniform(const ShaderUniform &uniform);
-
- inline PackUniformHash &uniforms() { return m_uniforms; }
- inline const PackUniformHash &uniforms() const { return m_uniforms; }
- UniformValue uniform(const int glslNameId) const { return m_uniforms.value(glslNameId); }
-
- struct NamedTexture
- {
- NamedTexture() {}
- NamedTexture(const int glslNameId, Qt3DCore::QNodeId texId, int uniformArrayIndex)
- : glslNameId(glslNameId)
- , texId(texId)
- , uniformArrayIndex(uniformArrayIndex)
- { }
-
- int glslNameId;
- Qt3DCore::QNodeId texId;
- int uniformArrayIndex;
- };
-
- inline QVector<NamedTexture> textures() const { return m_textures; }
- inline QVector<BlockToUBO> uniformBuffers() const { return m_uniformBuffers; }
- inline QVector<BlockToSSBO> shaderStorageBuffers() const { return m_shaderStorageBuffers; }
- inline QVector<ShaderUniform> submissionUniforms() const { return m_submissionUniforms; }
-private:
- PackUniformHash m_uniforms;
-
- QVector<NamedTexture> m_textures;
- QVector<BlockToUBO> m_uniformBuffers;
- QVector<BlockToSSBO> m_shaderStorageBuffers;
- QVector<ShaderUniform> m_submissionUniforms;
-
- friend class RenderView;
-};
-QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, ShaderParameterPack::NamedTexture, Q_PRIMITIVE_TYPE)
-
-} // namespace Render
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(Qt3DRender::Render::ShaderParameterPack)
-
-#endif // QT3DRENDER_RENDER_SHADERPARAMETERPACK_P_H
diff --git a/src/render/backend/shadervariables_p.h b/src/render/backend/shadervariables_p.h
deleted file mode 100644
index e0fa07dff..000000000
--- a/src/render/backend/shadervariables_p.h
+++ /dev/null
@@ -1,152 +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 QT3DRENDER_RENDER_SHADERVARIABLES_P_H
-#define QT3DRENDER_RENDER_SHADERVARIABLES_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 <Qt3DRender/qt3drender_global.h>
-#include <QOpenGLContext>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-
-namespace Render {
-
-struct ShaderAttribute
-{
- ShaderAttribute()
- : m_nameId(-1)
- , m_type(0)
- , m_size(0)
- , m_location(-1)
- {}
-
- QString m_name;
- int m_nameId;
- GLenum m_type;
- int m_size;
- int m_location;
-};
-QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, ShaderAttribute, Q_MOVABLE_TYPE)
-
-struct ShaderUniform
-{
- ShaderUniform()
- : m_nameId(-1)
- , m_type(GL_NONE)
- , m_size(0)
- , m_offset(-1)
- , m_location(-1)
- , m_blockIndex(-1)
- , m_arrayStride(-1)
- , m_matrixStride(-1)
- , m_rawByteSize(0)
- {}
-
- QString m_name;
- int m_nameId;
- GLenum m_type;
- int m_size;
- int m_offset; // -1 default, >= 0 if uniform defined in uniform block
- int m_location; // -1 if uniform defined in a uniform block
- int m_blockIndex; // -1 is the default, >= 0 if uniform defined in uniform block
- int m_arrayStride; // -1 is the default, >= 0 if uniform defined in uniform block and if it's an array
- int m_matrixStride; // -1 is the default, >= 0 uniform defined in uniform block and is a matrix
- uint m_rawByteSize; // contains byte size (size / type / strides)
- // size, offset and strides are in bytes
-};
-QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, ShaderUniform, Q_MOVABLE_TYPE)
-
-struct ShaderUniformBlock
-{
- ShaderUniformBlock()
- : m_nameId(-1)
- , m_index(-1)
- , m_binding(-1)
- , m_activeUniformsCount(0)
- , m_size(0)
- {}
-
- QString m_name;
- int m_nameId;
- int m_index;
- int m_binding;
- int m_activeUniformsCount;
- int m_size;
-};
-QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, ShaderUniformBlock, Q_MOVABLE_TYPE)
-
-struct ShaderStorageBlock
-{
- ShaderStorageBlock()
- : m_nameId(-1)
- , m_index(-1)
- , m_binding(-1)
- , m_size(0)
- , m_activeVariablesCount(0)
- {}
-
- QString m_name;
- int m_nameId;
- int m_index;
- int m_binding;
- int m_size;
- int m_activeVariablesCount;
-};
-QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, ShaderStorageBlock, Q_MOVABLE_TYPE)
-
-} // namespace Render
-
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE
-
-#endif // QT3DRENDER_RENDER_SHADERVARIABLES_P_H