summaryrefslogtreecommitdiffstats
path: root/src/runtime/dragon/geometry/dragonbuffervisitor_p.h
diff options
context:
space:
mode:
authorSvenn-Arne Dragly <svenn-arne.dragly@qt.io>2018-06-20 12:42:39 +0200
committerAndy Nichols <andy.nichols@qt.io>2018-10-14 10:00:22 +0000
commitb301530c33f007f03a338c46d942835d22893799 (patch)
tree59aab56001b899304746cd63b007954f9c0aa481 /src/runtime/dragon/geometry/dragonbuffervisitor_p.h
parentbb00314e858d0e0ba02c0ac105008e0d0f3d86d7 (diff)
Import Dragon Render Aspect Prototype
This change introduces an experimental render aspect written in a somewhat functional programming style with a goal of improving performance and safety. It introduces: - A task system that wraps around QAspectJob and functions. This makes dependencies explicit and verified at compile time, and automates passing results from one task to the next. This also simplifies caching results between frames. - An immutable/copy-on-write wrapper around backend objects. This is introduced to simplify data sharing between different threads and improve safety. - A new container with convenience functions for iterating over new, dirty and removed objects. This is introduced to simplify tracking the dirty state of frontend objects, through their backend representation, towards loading data in memory and finally onto the GPU. This render aspect supports the features needed by Qt3D Studio Runtime, but lacks some of the features currently present in Qt3D. This is the reason why it is currently being developed in qt3d-runtime. Once feature complete, it can be ported back to Qt3D as the default render aspect. To enable the Dragon Render Aspect just pass --dragon to the viewer application or enable the flag AwakenTheDragon when creating the Q3DSEngine. Co-authored-by: Andy Nichols <andy.nichols@qt.io> Change-Id: Ieabf62120ef0cd7727b8896a192e22d356f270bd Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/runtime/dragon/geometry/dragonbuffervisitor_p.h')
-rw-r--r--src/runtime/dragon/geometry/dragonbuffervisitor_p.h305
1 files changed, 305 insertions, 0 deletions
diff --git a/src/runtime/dragon/geometry/dragonbuffervisitor_p.h b/src/runtime/dragon/geometry/dragonbuffervisitor_p.h
new file mode 100644
index 0000000..8526e38
--- /dev/null
+++ b/src/runtime/dragon/geometry/dragonbuffervisitor_p.h
@@ -0,0 +1,305 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2018 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_BUFFERVISITOR_P_H
+#define QT3DRENDER_RENDER_BUFFERVISITOR_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 <private/dragonattribute_p.h>
+#include <private/dragonbuffer_p.h>
+#include <private/dragonbufferutils_p.h>
+#include <private/dragongeometryrenderer_p.h>
+#include <private/dragongeometry_p.h>
+
+#include <Qt3DRender/qattribute.h>
+
+#include <Qt3DCore/qnodeid.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DCore {
+class QEntity;
+}
+
+namespace Qt3DRender {
+namespace Dragon {
+
+
+template <typename ValueType, QAttribute::VertexBaseType VertexBaseType, uint dataSize>
+class Q_AUTOTEST_EXPORT BufferVisitor
+{
+public:
+ explicit BufferVisitor()
+ {
+ }
+ virtual ~BufferVisitor() { }
+
+ virtual void visit(uint ndx, ValueType x) {
+ Q_UNUSED(ndx); Q_UNUSED(x);
+ }
+ virtual void visit(uint ndx, ValueType x, ValueType y) {
+ Q_UNUSED(ndx); Q_UNUSED(x); Q_UNUSED(y);
+ }
+ virtual void visit(uint ndx, ValueType x, ValueType y, ValueType z) {
+ Q_UNUSED(ndx); Q_UNUSED(x); Q_UNUSED(y); Q_UNUSED(z);
+ }
+ virtual void visit(uint ndx, ValueType x, ValueType y, ValueType z, ValueType w) {
+ Q_UNUSED(ndx); Q_UNUSED(x); Q_UNUSED(y); Q_UNUSED(z); Q_UNUSED(w);
+ }
+
+ bool apply(const Attribute &attribute,
+ const Buffer &attributeBuffer,
+ int drawVertexCount)
+ {
+ if (attribute.vertexBaseType() != VertexBaseType)
+ return false;
+ if (attribute.vertexSize() < dataSize)
+ return false;
+
+ auto data = attributeBuffer.m_data;
+ auto buffer = BufferTypeInfo::castToType<VertexBaseType>(data, attribute.byteOffset());
+
+ switch (dataSize) {
+ case 1: traverseCoordinates1(buffer, attribute.byteStride(), drawVertexCount); break;
+ case 2: traverseCoordinates2(buffer, attribute.byteStride(), drawVertexCount); break;
+ case 3: traverseCoordinates3(buffer, attribute.byteStride(), drawVertexCount); break;
+ case 4: traverseCoordinates4(buffer, attribute.byteStride(), drawVertexCount); break;
+ default: Q_UNREACHABLE();
+ }
+
+ return true;
+ }
+
+ bool apply(const Attribute &attribute,
+ const Buffer &attributeBuffer,
+ const Attribute &indexAttribute,
+ const Buffer &indexBuffer,
+ int drawVertexCount,
+ bool primitiveRestartEnabled,
+ int primitiveRestartIndex)
+ {
+ if (attribute.vertexBaseType() != VertexBaseType)
+ return false;
+ if (attribute.vertexSize() < dataSize)
+ return false;
+
+ auto data = attributeBuffer.m_data;
+ auto buffer = BufferTypeInfo::castToType<VertexBaseType>(data, attribute.byteOffset());
+
+ auto indexData = indexBuffer.m_data;
+ if (indexAttribute.vertexBaseType() == QAttribute::UnsignedShort) {
+ auto indexBuffer = BufferTypeInfo::castToType<QAttribute::UnsignedShort>(indexData, indexAttribute.byteOffset());
+ switch (dataSize) {
+ case 1: traverseCoordinates1Indexed(buffer, attribute.byteStride(), indexBuffer, drawVertexCount,
+ primitiveRestartEnabled, primitiveRestartIndex);
+ break;
+ case 2: traverseCoordinates2Indexed(buffer, attribute.byteStride(), indexBuffer, drawVertexCount,
+ primitiveRestartEnabled, primitiveRestartIndex);
+ break;
+ case 3: traverseCoordinates3Indexed(buffer, attribute.byteStride(), indexBuffer, drawVertexCount,
+ primitiveRestartEnabled, primitiveRestartIndex);
+ break;
+ case 4: traverseCoordinates4Indexed(buffer, attribute.byteStride(), indexBuffer, drawVertexCount,
+ primitiveRestartEnabled, primitiveRestartIndex);
+ break;
+ default: Q_UNREACHABLE();
+ }
+ } else {
+ auto indexBuffer = BufferTypeInfo::castToType<QAttribute::UnsignedInt>(indexData, indexAttribute.byteOffset());
+ switch (dataSize) {
+ case 1: traverseCoordinates1Indexed(buffer, attribute.byteStride(), indexBuffer, drawVertexCount,
+ primitiveRestartEnabled, primitiveRestartIndex);
+ break;
+ case 2: traverseCoordinates2Indexed(buffer, attribute.byteStride(), indexBuffer, drawVertexCount,
+ primitiveRestartEnabled, primitiveRestartIndex);
+ break;
+ case 3: traverseCoordinates3Indexed(buffer, attribute.byteStride(), indexBuffer, drawVertexCount,
+ primitiveRestartEnabled, primitiveRestartIndex);
+ break;
+ case 4: traverseCoordinates4Indexed(buffer, attribute.byteStride(), indexBuffer, drawVertexCount,
+ primitiveRestartEnabled, primitiveRestartIndex);
+ break;
+ default: Q_UNREACHABLE();
+ }
+ }
+
+ return true;
+ }
+
+protected:
+
+ template <typename Coordinate>
+ void traverseCoordinates1(Coordinate *coordinates,
+ const uint byteStride,
+ const uint count)
+ {
+ const uint stride = byteStride / sizeof(Coordinate);
+ for (uint ndx = 0; ndx < count; ++ndx) {
+ visit(ndx, coordinates[0]);
+ coordinates += stride;
+ }
+ }
+
+ template <typename Coordinate, typename IndexElem>
+ void traverseCoordinates1Indexed(Coordinate *coordinates,
+ const uint byteStride,
+ IndexElem *indices,
+ const uint count,
+ bool primitiveRestartEnabled,
+ int primitiveRestartIndex)
+ {
+ const uint stride = byteStride / sizeof(Coordinate);
+ for (uint i = 0; i < count; ++i) {
+ if (!primitiveRestartEnabled || (int) indices[i] != primitiveRestartIndex) {
+ const uint n = stride * indices[i];
+ visit(i, coordinates[n]);
+ }
+ }
+ }
+
+ template <typename Coordinate>
+ void traverseCoordinates2(Coordinate *coordinates,
+ const uint byteStride,
+ const uint count)
+ {
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 2;
+ for (uint ndx = 0; ndx < count; ++ndx) {
+ visit(ndx, coordinates[0], coordinates[1]);
+ coordinates += stride;
+ }
+ }
+
+
+ template <typename Coordinate, typename IndexElem>
+ void traverseCoordinates2Indexed(Coordinate *coordinates,
+ const uint byteStride,
+ IndexElem *indices,
+ const uint count,
+ bool primitiveRestartEnabled,
+ int primitiveRestartIndex)
+ {
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 2;
+ for (uint i = 0; i < count; ++i) {
+ if (!primitiveRestartEnabled || (int) indices[i] != primitiveRestartIndex) {
+ const uint n = stride * indices[i];
+ visit(i, coordinates[n], coordinates[n + 1]);
+ }
+ }
+ }
+
+ template <typename Coordinate>
+ void traverseCoordinates3(Coordinate *coordinates,
+ const uint byteStride,
+ const uint count)
+ {
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 3;
+ for (uint ndx = 0; ndx < count; ++ndx) {
+ visit(ndx, coordinates[0], coordinates[1], coordinates[2]);
+ coordinates += stride;
+ }
+ }
+
+ template <typename Coordinate, typename IndexElem>
+ void traverseCoordinates3Indexed(Coordinate *coordinates,
+ const uint byteStride,
+ IndexElem *indices,
+ const uint count,
+ bool primitiveRestartEnabled,
+ int primitiveRestartIndex)
+ {
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 3;
+ for (uint i = 0; i < count; ++i) {
+ if (!primitiveRestartEnabled || (int) indices[i] != primitiveRestartIndex) {
+ const uint n = stride * indices[i];
+ visit(i, coordinates[n], coordinates[n + 1], coordinates[n + 2]);
+ }
+ }
+ }
+
+ template <typename Coordinate>
+ void traverseCoordinates4(Coordinate *coordinates,
+ const uint byteStride,
+ const uint count)
+ {
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 4;
+ for (uint ndx = 0; ndx < count; ++ndx) {
+ visit(ndx, coordinates[0], coordinates[1], coordinates[2], coordinates[3]);
+ coordinates += stride;
+ }
+ }
+
+ template <typename Coordinate, typename IndexElem>
+ void traverseCoordinates4Indexed(Coordinate *coordinates,
+ const uint byteStride,
+ IndexElem *indices,
+ const uint count,
+ bool primitiveRestartEnabled,
+ int primitiveRestartIndex)
+ {
+ const uint stride = byteStride ? byteStride / sizeof(Coordinate) : 4;
+ for (uint i = 0; i < count; ++i) {
+ if (!primitiveRestartEnabled || (int) indices[i] != primitiveRestartIndex) {
+ const uint n = stride * indices[i];
+ visit(i, coordinates[n], coordinates[n + 1], coordinates[n + 2], coordinates[n + 3]);
+ }
+ }
+ }
+};
+
+typedef BufferVisitor<float, QAttribute::Float, 3> Buffer3fVisitor;
+
+} // namespace Render
+
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
+
+
+#endif // QT3DRENDER_RENDER_BUFFERVISITOR_P_H