1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#ifndef QSSGSCENERENDERER_H
5#define QSSGSCENERENDERER_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 <QtQuick3DRuntimeRender/private/qssgrendercontextcore_p.h>
19
20#include <qsgtextureprovider.h>
21#include <qsgrendernode.h>
22#include <QSGSimpleTextureNode>
23
24#include <QtQuick3D/private/qquick3dviewport_p.h>
25#include <QtQuick3DRuntimeRender/private/qssgrenderlayer_p.h>
26#include <QtQuick3DRuntimeRender/private/qssgrhieffectsystem_p.h>
27#include <QtQuick3DRuntimeRender/private/qssgrenderer_p.h>
28
29#include <optional>
30
31#include "qquick3dsceneenvironment_p.h"
32
33QT_BEGIN_NAMESPACE
34
35
36class QQuick3DSceneManager;
37class QQuick3DViewport;
38struct QSSGRenderLayer;
39
40class QQuick3DSceneRenderer
41{
42 using PickResultList = QVarLengthArray<QSSGRenderPickResult, 20>;
43public:
44 explicit QQuick3DSceneRenderer(const std::shared_ptr<QSSGRenderContextInterface> &rci);
45 ~QQuick3DSceneRenderer();
46
47 static QSSGRenderLayer::TonemapMode getTonemapMode(const QQuick3DSceneEnvironment &environment)
48 {
49 return environment.useBuiltinTonemapper() ? QSSGRenderLayer::TonemapMode(environment.tonemapMode())
50 : QSSGRenderLayer::TonemapMode::None;
51 }
52
53protected:
54 QRhiTexture *renderToRhiTexture(QQuickWindow *qw);
55 void beginFrame();
56 void endFrame();
57 void rhiPrepare(const QRect &viewport, qreal displayPixelRatio);
58 void rhiRender();
59 void synchronize(QQuick3DViewport *view3D, const QSize &size, float dpr);
60 void invalidateFramebufferObject();
61 QSize surfaceSize() const { return m_surfaceSize; }
62 void releaseCachedResources();
63
64 std::optional<QSSGRenderRay> getRayFromViewportPos(const QPointF &pos);
65 QSSGRenderPickResult syncPick(const QSSGRenderRay &ray);
66 QSSGRenderPickResult syncPickOne(const QSSGRenderRay &ray, QSSGRenderNode *node);
67 PickResultList syncPickAll(const QSSGRenderRay &ray);
68
69 void setGlobalPickingEnabled(bool isEnabled);
70
71 QQuick3DRenderStats *renderStats();
72
73private:
74 void releaseAaDependentRhiResources();
75 void updateLayerNode(QQuick3DViewport *view3D, const QList<QSSGRenderGraphObject *> &resourceLoaders);
76 void addNodeToLayer(QSSGRenderNode *node);
77 void removeNodeFromLayer(QSSGRenderNode *node);
78 std::shared_ptr<QSSGRenderContextInterface> m_sgContext;
79 QSSGRenderLayer *m_layer = nullptr;
80 QPointer<QQuick3DWindowAttachment> winAttacment;
81 QSize m_surfaceSize;
82 SGFramebufferObjectNode *fboNode = nullptr;
83 bool m_aaIsDirty = true;
84
85 // RHI
86 QRhiTexture *m_texture = nullptr;
87 // the rt is set up to output into m_texture or m_ssaaTexture or m_msaaRenderBuffer(+resolve into m_texture)
88 QRhiTextureRenderTarget *m_textureRenderTarget = nullptr;
89 QRhiRenderPassDescriptor *m_textureRenderPassDescriptor = nullptr;
90 // used by the draw quad that does m_ssaaTexture -> m_texture
91 QRhiTextureRenderTarget *m_ssaaTextureToTextureRenderTarget = nullptr;
92 QRhiRenderPassDescriptor *m_ssaaTextureToTextureRenderPassDescriptor = nullptr;
93 QRhiRenderBuffer *m_msaaRenderBuffer = nullptr;
94 QRhiTexture *m_ssaaTexture = nullptr;
95 QRhiTexture *m_temporalAATexture = nullptr;
96 QRhiTexture *m_prevTempAATexture = nullptr;
97 QRhiTextureRenderTarget *m_temporalAARenderTarget = nullptr;
98 QRhiRenderPassDescriptor *m_temporalAARenderPassDescriptor = nullptr;
99 QRhiRenderBuffer *m_depthStencilBuffer = nullptr;
100 bool m_textureNeedsFlip = true;
101 QSSGRenderLayer::Background m_backgroundMode;
102 QColor m_userBackgroundColor = Qt::black;
103 QColor m_linearBackgroundColor = Qt::black;
104 QColor m_tonemappedBackgroundColor = Qt::black;
105 int m_samples = 1;
106 QSSGRhiEffectSystem *m_effectSystem = nullptr;
107
108 QPointer<QQuick3DRenderStats> m_renderStats;
109
110 QSSGRenderNode *m_sceneRootNode = nullptr;
111 QSSGRenderNode *m_importRootNode = nullptr;
112
113 float m_ssaaMultiplier = 1.5f;
114
115 bool m_prepared = false;
116
117 int requestedFramesCount = 0;
118 bool m_postProcessingStack = false;
119 Q_QUICK3D_PROFILE_ID
120
121 friend class SGFramebufferObjectNode;
122 friend class QQuick3DSGRenderNode;
123 friend class QQuick3DSGDirectRenderer;
124 friend class QQuick3DViewport;
125 friend struct ViewportTransformHelper;
126};
127
128namespace QQuick3DRenderLayerHelpers {
129Q_QUICK3D_EXPORT void updateLayerNodeHelper(const QQuick3DViewport &view3D, QSSGRenderLayer &layerNode, bool &aaIsDirty, bool &temporalIsDirty, float &ssaaMultiplier);
130}
131
132class SGFramebufferObjectNode final : public QSGTextureProvider, public QSGSimpleTextureNode
133{
134 Q_OBJECT
135
136public:
137 SGFramebufferObjectNode();
138 ~SGFramebufferObjectNode() override;
139
140 void scheduleRender();
141
142 QSGTexture *texture() const override;
143
144 void preprocess() override;
145
146public Q_SLOTS:
147 void render();
148
149 void handleScreenChange();
150
151public:
152 QQuickWindow *window;
153 QQuick3DSceneRenderer *renderer;
154 QQuick3DViewport *quickFbo;
155
156 bool renderPending;
157 bool invalidatePending;
158
159 qreal devicePixelRatio;
160};
161
162class QQuick3DSGRenderNode final : public QSGRenderNode
163{
164public:
165 ~QQuick3DSGRenderNode();
166 void prepare() override;
167 StateFlags changedStates() const override;
168 void render(const RenderState *state) override;
169 void releaseResources() override;
170 RenderingFlags flags() const override;
171public:
172 QQuickWindow *window = nullptr;
173 QQuick3DSceneRenderer *renderer = nullptr;
174};
175
176class QQuick3DSGDirectRenderer : public QObject
177{
178 Q_OBJECT
179public:
180 enum QQuick3DSGDirectRendererMode {
181 Underlay,
182 Overlay
183 };
184 QQuick3DSGDirectRenderer(QQuick3DSceneRenderer *renderer, QQuickWindow *window, QQuick3DSGDirectRendererMode mode = Underlay);
185 ~QQuick3DSGDirectRenderer();
186
187 QQuick3DSceneRenderer *renderer() { return m_renderer; }
188 void setViewport(const QRectF &viewport);
189
190 void requestRender();
191 void setVisibility(bool visible);
192
193private Q_SLOTS:
194 void prepare();
195 void render();
196
197private:
198 QQuick3DSceneRenderer *m_renderer = nullptr;
199 QQuickWindow *m_window = nullptr;
200 QQuick3DSGDirectRendererMode m_mode;
201 QRectF m_viewport;
202 bool m_isVisible = true;
203 QRhiTexture *m_rhiTexture = nullptr;
204 bool renderPending = false;
205};
206
207QT_END_NAMESPACE
208
209#endif // QSSGSCENERENDERER_H
210

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