1 | // Copyright (C) 2008-2012 NVIDIA Corporation. |
2 | // Copyright (C) 2019 The Qt Company Ltd. |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
4 | |
5 | #include "qssgrendercontextcore_p.h" |
6 | #include <QtQuick3DRuntimeRender/private/qssgrendernode_p.h> |
7 | #include <QtQuick3DRuntimeRender/private/qssgrenderbuffermanager_p.h> |
8 | #include <QtQuick3DRuntimeRender/private/qssgrendershadercache_p.h> |
9 | #include <QtQuick3DRuntimeRender/private/qssgrendercamera_p.h> |
10 | #include <QtQuick3DRuntimeRender/private/qssgrendershaderlibrarymanager_p.h> |
11 | #include <QtQuick3DRuntimeRender/private/qssgrendershadercodegenerator_p.h> |
12 | #include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterialshadergenerator_p.h> |
13 | #include <QtQuick3DRuntimeRender/private/qssgrhicustommaterialsystem_p.h> |
14 | #include <QtQuick3DRuntimeRender/private/qssgperframeallocator_p.h> |
15 | #include <QtQuick3DRuntimeRender/private/qssgrenderer_p.h> |
16 | #include <QtQuick3DRuntimeRender/private/qssgrendererutil_p.h> |
17 | #include <QtQuick3DRuntimeRender/private/qssgdebugdrawsystem_p.h> |
18 | |
19 | #include <QtQuick/private/qquickwindow_p.h> |
20 | |
21 | QT_BEGIN_NAMESPACE |
22 | |
23 | static bool loadPregenratedShaders() |
24 | { |
25 | return qEnvironmentVariableIntValue(varName: "QT_QUICK3D_DISABLE_GENSHADERS" ) == 0; |
26 | } |
27 | |
28 | void QSSGRenderContextInterface::init() |
29 | { |
30 | m_renderer->setRenderContextInterface(this); |
31 | |
32 | m_bufferManager->setRenderContextInterface(this); |
33 | |
34 | m_customMaterialSystem->setRenderContextInterface(this); |
35 | if (loadPregenratedShaders()) |
36 | m_shaderLibraryManager->loadPregeneratedShaderInfo(); |
37 | } |
38 | |
39 | void QSSGRenderContextInterface::releaseCachedResources() |
40 | { |
41 | m_renderer->releaseCachedResources(); |
42 | m_shaderCache->releaseCachedResources(); |
43 | m_customMaterialSystem->releaseCachedResources(); |
44 | m_bufferManager->releaseCachedResources(); |
45 | m_rhiContext->releaseCachedResources(); |
46 | } |
47 | |
48 | QSSGRenderContextInterface::QSSGRenderContextInterface(std::unique_ptr<QSSGBufferManager> &&bufferManager, |
49 | std::unique_ptr<QSSGRenderer> renderer, |
50 | std::shared_ptr<QSSGShaderLibraryManager> shaderLibraryManager, |
51 | std::unique_ptr<QSSGShaderCache> shaderCache, |
52 | std::unique_ptr<QSSGCustomMaterialSystem> customMaterialSystem, |
53 | std::unique_ptr<QSSGProgramGenerator> shaderProgramGenerator, |
54 | std::unique_ptr<QSSGRhiContext> ctx, |
55 | std::unique_ptr<QSSGDebugDrawSystem> debugDrawSystem) |
56 | : m_rhiContext(std::move(ctx)) |
57 | , m_shaderCache(std::move(shaderCache)) |
58 | , m_bufferManager(std::move(bufferManager)) |
59 | , m_renderer(std::move(renderer)) |
60 | , m_shaderLibraryManager(std::move(shaderLibraryManager)) |
61 | , m_customMaterialSystem(std::move(customMaterialSystem)) |
62 | , m_shaderProgramGenerator(std::move(shaderProgramGenerator)) |
63 | , m_debugDrawSystem(std::move(debugDrawSystem)) |
64 | { |
65 | init(); |
66 | } |
67 | |
68 | // The shader library is a global object, not per-QQuickWindow, hence not owned |
69 | // by the QSSGRenderContextInterface. |
70 | static const std::shared_ptr<QSSGShaderLibraryManager> &q3ds_shaderLibraryManager() |
71 | { |
72 | static auto shaderLibraryManager = std::make_shared<QSSGShaderLibraryManager>(); |
73 | return shaderLibraryManager; |
74 | } |
75 | |
76 | QSSGRenderContextInterface::QSSGRenderContextInterface(QRhi *rhi) |
77 | : m_rhiContext(new QSSGRhiContext(rhi)) |
78 | , m_shaderCache(new QSSGShaderCache(*m_rhiContext)) |
79 | , m_bufferManager(new QSSGBufferManager()) |
80 | , m_renderer(new QSSGRenderer()) |
81 | , m_shaderLibraryManager(q3ds_shaderLibraryManager()) |
82 | , m_customMaterialSystem(new QSSGCustomMaterialSystem()) |
83 | , m_shaderProgramGenerator(new QSSGProgramGenerator()) |
84 | , m_debugDrawSystem(new QSSGDebugDrawSystem()) |
85 | { |
86 | init(); |
87 | } |
88 | |
89 | QSSGRenderContextInterface::~QSSGRenderContextInterface() |
90 | { |
91 | m_renderer->releaseCachedResources(); |
92 | } |
93 | |
94 | const std::unique_ptr<QSSGRenderer> &QSSGRenderContextInterface::renderer() const |
95 | { |
96 | return m_renderer; |
97 | } |
98 | |
99 | const std::unique_ptr<QSSGBufferManager> &QSSGRenderContextInterface::bufferManager() const |
100 | { |
101 | return m_bufferManager; |
102 | } |
103 | |
104 | const std::unique_ptr<QSSGRhiContext> &QSSGRenderContextInterface::rhiContext() const |
105 | { |
106 | return m_rhiContext; |
107 | } |
108 | |
109 | const std::unique_ptr<QSSGShaderCache> &QSSGRenderContextInterface::shaderCache() const |
110 | { |
111 | return m_shaderCache; |
112 | } |
113 | |
114 | const std::shared_ptr<QSSGShaderLibraryManager> &QSSGRenderContextInterface::shaderLibraryManager() const |
115 | { |
116 | return m_shaderLibraryManager; |
117 | } |
118 | |
119 | const std::unique_ptr<QSSGCustomMaterialSystem> &QSSGRenderContextInterface::customMaterialSystem() const |
120 | { |
121 | return m_customMaterialSystem; |
122 | } |
123 | |
124 | const std::unique_ptr<QSSGProgramGenerator> &QSSGRenderContextInterface::shaderProgramGenerator() const |
125 | { |
126 | return m_shaderProgramGenerator; |
127 | } |
128 | |
129 | const std::unique_ptr<QSSGDebugDrawSystem> &QSSGRenderContextInterface::debugDrawSystem() const |
130 | { |
131 | return m_debugDrawSystem; |
132 | } |
133 | |
134 | QRhi *QSSGRenderContextInterface::rhi() const |
135 | { |
136 | return m_rhiContext->rhi(); |
137 | } |
138 | |
139 | void QSSGRenderContextInterface::cleanupResources(QList<QSSGRenderGraphObject *> &resources) |
140 | { |
141 | m_renderer->cleanupResources(resources); |
142 | } |
143 | |
144 | void QSSGRenderContextInterface::cleanupResources(QSet<QSSGRenderGraphObject *> &resources) |
145 | { |
146 | m_renderer->cleanupResources(resources); |
147 | } |
148 | |
149 | void QSSGRenderContextInterface::cleanupUnreferencedBuffers(QSSGRenderLayer *inLayer) |
150 | { |
151 | // Now check for unreferenced buffers and release them if necessary |
152 | m_bufferManager->cleanupUnreferencedBuffers(frameId: m_frameCount, layer: inLayer); |
153 | } |
154 | |
155 | |
156 | void QSSGRenderContextInterface::resetResourceCounters(QSSGRenderLayer *inLayer) |
157 | { |
158 | m_bufferManager->resetUsageCounters(frameId: m_frameCount, layer: inLayer); |
159 | } |
160 | |
161 | void QSSGRenderContextInterface::beginFrame(QSSGRenderLayer *layer, bool allowRecursion) |
162 | { |
163 | if (allowRecursion) { |
164 | if (m_activeFrameRef++ != 0) |
165 | return; |
166 | } |
167 | |
168 | m_perFrameAllocator.reset(); |
169 | m_renderer->beginFrame(layer); |
170 | resetResourceCounters(inLayer: layer); |
171 | } |
172 | |
173 | bool QSSGRenderContextInterface::prepareLayerForRender(QSSGRenderLayer &inLayer) |
174 | { |
175 | return m_renderer->prepareLayerForRender(inLayer); |
176 | } |
177 | |
178 | void QSSGRenderContextInterface::rhiPrepare(QSSGRenderLayer &inLayer) |
179 | { |
180 | m_renderer->rhiPrepare(inLayer); |
181 | } |
182 | |
183 | void QSSGRenderContextInterface::rhiRender(QSSGRenderLayer &inLayer) |
184 | { |
185 | m_renderer->rhiRender(inLayer); |
186 | } |
187 | |
188 | bool QSSGRenderContextInterface::endFrame(QSSGRenderLayer *layer, bool allowRecursion) |
189 | { |
190 | if (allowRecursion) { |
191 | if (--m_activeFrameRef != 0) |
192 | return false; |
193 | } |
194 | |
195 | cleanupUnreferencedBuffers(inLayer: layer); |
196 | |
197 | m_renderer->endFrame(layer); |
198 | ++m_frameCount; |
199 | |
200 | return true; |
201 | } |
202 | |
203 | QT_END_NAMESPACE |
204 | |
205 | |