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
21QT_BEGIN_NAMESPACE
22
23static bool loadPregenratedShaders()
24{
25 return qEnvironmentVariableIntValue(varName: "QT_QUICK3D_DISABLE_GENSHADERS") == 0;
26}
27
28void 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
39void 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
48QSSGRenderContextInterface::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.
70static const std::shared_ptr<QSSGShaderLibraryManager> &q3ds_shaderLibraryManager()
71{
72 static auto shaderLibraryManager = std::make_shared<QSSGShaderLibraryManager>();
73 return shaderLibraryManager;
74}
75
76QSSGRenderContextInterface::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
89QSSGRenderContextInterface::~QSSGRenderContextInterface()
90{
91 m_renderer->releaseCachedResources();
92}
93
94const std::unique_ptr<QSSGRenderer> &QSSGRenderContextInterface::renderer() const
95{
96 return m_renderer;
97}
98
99const std::unique_ptr<QSSGBufferManager> &QSSGRenderContextInterface::bufferManager() const
100{
101 return m_bufferManager;
102}
103
104const std::unique_ptr<QSSGRhiContext> &QSSGRenderContextInterface::rhiContext() const
105{
106 return m_rhiContext;
107}
108
109const std::unique_ptr<QSSGShaderCache> &QSSGRenderContextInterface::shaderCache() const
110{
111 return m_shaderCache;
112}
113
114const std::shared_ptr<QSSGShaderLibraryManager> &QSSGRenderContextInterface::shaderLibraryManager() const
115{
116 return m_shaderLibraryManager;
117}
118
119const std::unique_ptr<QSSGCustomMaterialSystem> &QSSGRenderContextInterface::customMaterialSystem() const
120{
121 return m_customMaterialSystem;
122}
123
124const std::unique_ptr<QSSGProgramGenerator> &QSSGRenderContextInterface::shaderProgramGenerator() const
125{
126 return m_shaderProgramGenerator;
127}
128
129const std::unique_ptr<QSSGDebugDrawSystem> &QSSGRenderContextInterface::debugDrawSystem() const
130{
131 return m_debugDrawSystem;
132}
133
134QRhi *QSSGRenderContextInterface::rhi() const
135{
136 return m_rhiContext->rhi();
137}
138
139void QSSGRenderContextInterface::cleanupResources(QList<QSSGRenderGraphObject *> &resources)
140{
141 m_renderer->cleanupResources(resources);
142}
143
144void QSSGRenderContextInterface::cleanupResources(QSet<QSSGRenderGraphObject *> &resources)
145{
146 m_renderer->cleanupResources(resources);
147}
148
149void 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
156void QSSGRenderContextInterface::resetResourceCounters(QSSGRenderLayer *inLayer)
157{
158 m_bufferManager->resetUsageCounters(frameId: m_frameCount, layer: inLayer);
159}
160
161void 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
173bool QSSGRenderContextInterface::prepareLayerForRender(QSSGRenderLayer &inLayer)
174{
175 return m_renderer->prepareLayerForRender(inLayer);
176}
177
178void QSSGRenderContextInterface::rhiPrepare(QSSGRenderLayer &inLayer)
179{
180 m_renderer->rhiPrepare(inLayer);
181}
182
183void QSSGRenderContextInterface::rhiRender(QSSGRenderLayer &inLayer)
184{
185 m_renderer->rhiRender(inLayer);
186}
187
188bool 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
203QT_END_NAMESPACE
204
205

source code of qtquick3d/src/runtimerender/qssgrendercontextcore.cpp