1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#ifndef QSSGSCENEMANAGER_P_H
5#define QSSGSCENEMANAGER_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/QObject>
19#include <QtCore/QSet>
20
21#include <QtQuick3D/private/qtquick3dglobal_p.h>
22
23#include "qquick3dobject_p.h"
24#include "qquick3dnode_p.h"
25
26QT_BEGIN_NAMESPACE
27
28class QSGDynamicTexture;
29class QQuickWindow;
30class QSSGBufferManager;
31class QSSGRenderContextInterface;
32
33class Q_QUICK3D_PRIVATE_EXPORT QQuick3DWindowAttachment : public QObject
34{
35 Q_OBJECT
36public:
37 explicit QQuick3DWindowAttachment(QQuickWindow *window);
38 ~QQuick3DWindowAttachment() override;
39
40 Q_INVOKABLE void preSync();
41 Q_INVOKABLE void cleanupResources();
42 Q_INVOKABLE bool synchronize(QSet<QSSGRenderGraphObject *> &resourceLoaders);
43 Q_INVOKABLE void requestUpdate();
44
45 QQuickWindow *window() const;
46
47 const std::shared_ptr<QSSGRenderContextInterface> &rci() const { return m_rci; }
48 void setRci(const std::shared_ptr<QSSGRenderContextInterface> &rciptr);
49
50 void registerSceneManager(QQuick3DSceneManager &manager);
51 void unregisterSceneManager(QQuick3DSceneManager &manager);
52
53 void queueForCleanup(QSSGRenderGraphObject *obj);
54 void queueForCleanup(QQuick3DSceneManager *manager);
55
56Q_SIGNALS:
57 void releaseCachedResources();
58 void renderContextInterfaceChanged();
59
60private:
61 Q_INVOKABLE void onReleaseCachedResources();
62 Q_INVOKABLE void onInvalidated();
63
64 QPointer<QQuickWindow> m_window;
65 std::shared_ptr<QSSGRenderContextInterface> m_rci;
66 QList<QQuick3DSceneManager *> sceneManagers;
67 QList<QQuick3DSceneManager *> sceneManagerCleanupQueue;
68 QList<QSSGRenderGraphObject *> pendingResourceCleanupQueue;
69 QSet<QSSGRenderGraphObject *> resourceCleanupQueue;
70};
71
72class Q_QUICK3D_PRIVATE_EXPORT QQuick3DSceneManager : public QObject
73{
74 Q_OBJECT
75public:
76 explicit QQuick3DSceneManager(QObject *parent = nullptr);
77 ~QQuick3DSceneManager() override;
78
79 void setWindow(QQuickWindow *window);
80 QQuickWindow *window();
81
82 void dirtyItem(QQuick3DObject *item);
83 void requestUpdate();
84 void cleanup(QSSGRenderGraphObject *item);
85
86 void polishItems();
87 void forcePolish();
88 void sync();
89 void preSync();
90
91 bool cleanupNodes();
92 bool updateDirtyResourceNodes();
93 void updateDirtySpatialNodes();
94 void updateDiryExtensions();
95
96 void updateDirtyResource(QQuick3DObject *resourceObject);
97 void updateDirtySpatialNode(QQuick3DNode *spatialNode);
98 void updateBoundingBoxes(QSSGBufferManager &mgr);
99
100 QQuick3DObject *lookUpNode(const QSSGRenderGraphObject *node) const;
101
102 // Where the enumerator is placed will decide the priority it gets.
103 // NOTE: Place new list types before 'Count'.
104 // NOTE: InstanceNodes are nodes that have an instance root set, we'll process these
105 // after the other nodes but before light nodes; this implies that lights are not good candidates
106 // for being instance roots...
107 enum class NodePriority { Skeleton, Other, ModelWithInstanceRoot, Lights, Count };
108 enum class ResourcePriority { TextureData, Texture, Other, Count };
109 enum class ExtensionPriority { RenderExtension, Count };
110
111 static inline size_t resourceListIndex(QSSGRenderGraphObject::Type type)
112 {
113 Q_ASSERT(!QSSGRenderGraphObject::isNodeType(type));
114
115 if (QSSGRenderGraphObject::isTexture(type))
116 return size_t(ResourcePriority::Texture);
117
118 if (type == QSSGRenderGraphObject::Type::TextureData)
119 return size_t(ResourcePriority::TextureData);
120
121 return size_t(ResourcePriority::Other);
122 }
123
124 static inline size_t nodeListIndex(QSSGRenderGraphObject::Type type)
125 {
126 Q_ASSERT(QSSGRenderGraphObject::isNodeType(type));
127
128 if (QSSGRenderGraphObject::isLight(type))
129 return size_t(NodePriority::Lights);
130
131 if (type == QSSGRenderGraphObject::Type::Skeleton)
132 return size_t(NodePriority::Skeleton);
133
134 return size_t(NodePriority::Other);
135 }
136
137 static constexpr size_t extensionListIndex(QSSGRenderGraphObject::Type type)
138 {
139 Q_ASSERT(QSSGRenderGraphObject::isExtension(type));
140
141 return size_t(ExtensionPriority::RenderExtension);
142 }
143
144 static QQuick3DWindowAttachment *getOrSetWindowAttachment(QQuickWindow &window);
145
146 QQuick3DObject *dirtyResources[size_t(ResourcePriority::Count)] {};
147 QQuick3DObject *dirtyNodes[size_t(NodePriority::Count)] {};
148 QQuick3DObject *dirtyExtensions[size_t(ExtensionPriority::Count)] {};
149
150 QList<QQuick3DObject *> dirtyBoundingBoxList;
151 QList<QSSGRenderGraphObject *> cleanupNodeList;
152 QList<QSSGRenderGraphObject *> resourceCleanupQueue;
153
154 QSet<QQuick3DObject *> parentlessItems;
155 QVector<QSGDynamicTexture *> qsgDynamicTextures;
156 QHash<const QSSGRenderGraphObject *, QQuick3DObject *> m_nodeMap;
157 QSet<QSSGRenderGraphObject *> resourceLoaders;
158 QQuickWindow *m_window = nullptr;
159 QPointer<QQuick3DWindowAttachment> wattached;
160 int inputHandlingEnabled = 0; // Holds the count of active item2Ds, input disabled if zero.
161 bool sharedResourceRemoved = false;
162 friend QQuick3DObject;
163
164Q_SIGNALS:
165 void needsUpdate();
166 void windowChanged();
167
168private Q_SLOTS:
169 bool updateResources(QQuick3DObject **listHead);
170 void updateNodes(QQuick3DObject **listHead);
171 void updateExtensions(QQuick3DObject **listHead);
172};
173
174QT_END_NAMESPACE
175
176QML_DECLARE_TYPE(QQuick3DSceneManager)
177
178#endif // QSSGSCENEMANAGER_P_H
179

source code of qtquick3d/src/quick3d/qquick3dscenemanager_p.h