1// Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
2// Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QT3DRENDER_RENDER_OPENGL_RENDERER_H
6#define QT3DRENDER_RENDER_OPENGL_RENDERER_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists for the convenience
13// of other Qt classes. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <Qt3DRender/qrenderaspect.h>
20#include <Qt3DRender/qtechnique.h>
21#include <Qt3DRender/private/handle_types_p.h>
22#include <Qt3DRender/private/abstractrenderer_p.h>
23#include <Qt3DCore/qaspectjob.h>
24#include <Qt3DRender/private/qt3drender_global_p.h>
25#include <Qt3DRender/private/rendersettings_p.h>
26#include <Qt3DRender/private/updateshaderdatatransformjob_p.h>
27#include <Qt3DRender/private/framecleanupjob_p.h>
28#include <Qt3DRender/private/sendbuffercapturejob_p.h>
29#include <Qt3DRender/private/genericlambdajob_p.h>
30#include <Qt3DRender/private/shaderbuilder_p.h>
31#include <Qt3DRender/private/lightgatherer_p.h>
32#include <Qt3DRender/private/texture_p.h>
33#include <Qt3DRender/private/filterentitybycomponentjob_p.h>
34#include <Qt3DRender/private/filtercompatibletechniquejob_p.h>
35#include <Qt3DRender/private/renderqueue_p.h>
36#include <Qt3DRender/private/renderercache_p.h>
37#include <Qt3DRender/private/renderviewinitializerjob_p.h>
38#include <shaderparameterpack_p.h>
39#include <logging_p.h>
40#include <gl_handle_types_p.h>
41#include <glfence_p.h>
42
43#include <QHash>
44#include <QMatrix4x4>
45#include <QObject>
46
47#include <QOpenGLShaderProgram>
48#include <QOpenGLVertexArrayObject>
49#include <QOpenGLBuffer>
50#include <QMutex>
51#include <QWaitCondition>
52#include <QAtomicInt>
53#include <QScopedPointer>
54#include <QSemaphore>
55#include <QMouseEvent>
56#include <QKeyEvent>
57
58#include <functional>
59
60#if defined(QT_BUILD_INTERNAL)
61class tst_Renderer;
62#endif
63
64QT_BEGIN_NAMESPACE
65
66class QSurface;
67class QScreen;
68
69namespace Qt3DCore {
70class QEntity;
71}
72
73namespace Qt3DRender {
74
75class QCamera;
76class QMaterial;
77class QShaderProgram;
78class QMesh;
79class QRenderPass;
80class QAbstractShapeMesh;
81struct GraphicsApiFilterData;
82class QSceneImporter;
83
84namespace Debug {
85class CommandExecuter;
86}
87
88namespace Render {
89
90namespace Profiling {
91class FrameProfiler;
92}
93
94class CameraLens;
95class FrameGraphNode;
96class Material;
97class Technique;
98class Shader;
99class Entity;
100class Effect;
101class RenderPass;
102class RenderStateSet;
103class VSyncFrameAdvanceService;
104class NodeManagers;
105class ResourceAccessor;
106
107using ComputableEntityFilter = FilterEntityByComponentJob<Render::ComputeCommand, Render::Material>;
108using ComputableEntityFilterPtr = QSharedPointer<ComputableEntityFilter>;
109using RenderableEntityFilter = FilterEntityByComponentJob<Render::GeometryRenderer, Render::Material>;
110using RenderableEntityFilterPtr = QSharedPointer<RenderableEntityFilter>;
111
112using SynchronizerJobPtr = GenericLambdaJobPtr<std::function<void()>>;
113using SynchronizerPostFramePtr = GenericLambdaJobAndPostFramePtr<std::function<void ()>, std::function<void (Qt3DCore::QAspectManager *)>>;
114#define CreateSynchronizerPostFramePtr(lambda, postlambda, type) \
115 SynchronizerPostFramePtr::create(lambda, postlambda, type, #type)
116
117namespace Debug {
118class ImGuiRenderer;
119}
120
121namespace OpenGL {
122
123class CommandThread;
124class SubmissionContext;
125class RenderCommand;
126class GLShader;
127class GLResourceManagers;
128class RenderView;
129
130class Q_AUTOTEST_EXPORT Renderer : public AbstractRenderer
131{
132public:
133 explicit Renderer();
134 ~Renderer();
135
136 void dumpInfo() const override;
137 API api() const override { return Qt3DRender::API::OpenGL; }
138
139 void setRenderDriver(RenderDriver driver) override;
140 RenderDriver renderDriver() const override;
141
142 qint64 time() const override;
143 void setTime(qint64 time) override;
144 void setJobsInLastFrame(int jobsInLastFrame) override;
145
146 void setAspect(QRenderAspect *aspect) override;
147 void setNodeManagers(NodeManagers *managers) override;
148 void setServices(Qt3DCore::QServiceLocator *services) override;
149 void setSurfaceExposed(bool exposed) override;
150
151 QRenderAspect *aspect() const override;
152 NodeManagers *nodeManagers() const override;
153 Qt3DCore::QServiceLocator *services() const override { return m_services; }
154
155 void initialize() override;
156 void shutdown() override;
157 void releaseGraphicsResources() override;
158
159 void render(bool swapBuffers = true) override;
160 void cleanGraphicsResources() override;
161
162 bool isRunning() const override { return m_running.loadRelaxed(); }
163
164 void setSceneRoot(Entity *sgRoot) override;
165 Entity *sceneRoot() const override { return m_renderSceneRoot; }
166
167 FrameGraphNode *frameGraphRoot() const override;
168 RenderQueue<RenderView> *renderQueue() { return &m_renderQueue; }
169
170 void markDirty(BackendNodeDirtySet changes, BackendNode *node) override;
171 BackendNodeDirtySet dirtyBits() override;
172
173#if defined(QT_BUILD_INTERNAL)
174 void clearDirtyBits(BackendNodeDirtySet changes) override;
175#endif
176 bool shouldRender() const override;
177 void skipNextFrame() override;
178 void jobsDone(Qt3DCore::QAspectManager *manager) override;
179
180 bool processMouseEvent(QObject *object, QMouseEvent *event) override;
181 bool processKeyEvent(QObject *object, QKeyEvent *event) override;
182
183 std::vector<Qt3DCore::QAspectJobPtr> preRenderingJobs() override;
184 std::vector<Qt3DCore::QAspectJobPtr> renderBinJobs() override;
185 inline FrameCleanupJobPtr frameCleanupJob() const { return m_cleanupJob; }
186 inline UpdateShaderDataTransformJobPtr updateShaderDataTransformJob() const { return m_updateShaderDataTransformJob; }
187 inline FilterCompatibleTechniqueJobPtr filterCompatibleTechniqueJob() const { return m_filterCompatibleTechniqueJob; }
188 inline SynchronizerPostFramePtr introspectShadersJob() const { return m_introspectShaderJob; }
189 inline Qt3DCore::QAspectJobPtr bufferGathererJob() const { return m_bufferGathererJob; }
190 inline Qt3DCore::QAspectJobPtr textureGathererJob() const { return m_textureGathererJob; }
191 inline LightGathererPtr lightGathererJob() const { return m_lightGathererJob; }
192 inline RenderableEntityFilterPtr renderableEntityFilterJob() const { return m_renderableEntityFilterJob; }
193 inline ComputableEntityFilterPtr computableEntityFilterJob() const { return m_computableEntityFilterJob; }
194
195 Qt3DCore::QAbstractFrameAdvanceService *frameAdvanceService() const override;
196
197 void setSettings(RenderSettings *settings) override;
198 RenderSettings *settings() const override;
199 QOpenGLContext *shareContext() const override;
200
201 inline GLResourceManagers *glResourceManagers() const { return m_glResourceManagers; }
202
203 void updateGLResources();
204 void updateTexture(Texture *texture);
205 void cleanupTexture(Qt3DCore::QNodeId cleanedUpTextureId);
206 void cleanupShader(const Shader *shader);
207 void downloadGLBuffers();
208 void blitFramebuffer(Qt3DCore::QNodeId inputRenderTargetId,
209 Qt3DCore::QNodeId outputRenderTargetId,
210 QRect inputRect,
211 QRect outputRect,
212 GLuint defaultFramebuffer);
213
214 void prepareCommandsSubmission(const std::vector<RenderView *> &renderViews);
215 bool executeCommandsSubmission(RenderView *rv);
216 bool updateVAOWithAttributes(Geometry *geometry,
217 const RenderCommand *command,
218 GLShader *shader,
219 bool forceUpdate);
220
221 bool requiresVAOAttributeUpdate(Geometry *geometry,
222 const RenderCommand *command) const;
223
224 // For Scene3D/Scene2D rendering
225 void setOpenGLContext(QOpenGLContext *context) override;
226 void setRHIContext(QRhi *) override {};
227 void setDefaultRHIRenderTarget(QRhiRenderTarget *) override {};
228 void setRHICommandBuffer(QRhiCommandBuffer *) override {};
229 bool accessOpenGLTexture(Qt3DCore::QNodeId nodeId,
230 QOpenGLTexture **texture,
231 QMutex **lock,
232 bool readonly) override;
233 QSharedPointer<RenderBackendResourceAccessor> resourceAccessor() const override;
234
235
236 const GraphicsApiFilterData *contextInfo() const override;
237 SubmissionContext *submissionContext() const;
238
239 inline RenderStateSet *defaultRenderState() const { return m_defaultRenderStateSet; }
240
241 void enqueueRenderView(RenderView *renderView, int submitOrder);
242 bool waitUntilReadyToSubmit();
243
244 QVariant executeCommand(const QStringList &args) override;
245 void setOffscreenSurfaceHelper(OffscreenSurfaceHelper *helper) override;
246 QSurfaceFormat format() override;
247
248 struct ViewSubmissionResultData
249 {
250 ViewSubmissionResultData()
251 : lastBoundFBOId(0)
252 , surface(nullptr)
253 {}
254
255 uint lastBoundFBOId;
256 QSurface *surface;
257 };
258
259 ViewSubmissionResultData submitRenderViews(const std::vector<RenderView *> &renderViews);
260
261 RendererCache<RenderCommand> *cache() { return &m_cache; }
262 void setScreen(QScreen *scr) override;
263 QScreen *screen() const override;
264
265#ifdef QT3D_RENDER_UNIT_TESTS
266public:
267#else
268
269private:
270#endif
271 Profiling::FrameProfiler *activeProfiler() const;
272
273 Qt3DCore::QServiceLocator *m_services;
274 QRenderAspect *m_aspect;
275 NodeManagers *m_nodesManager;
276
277 // Frame graph root
278 Qt3DCore::QNodeId m_frameGraphRootUuid;
279
280 Entity *m_renderSceneRoot;
281
282 // Fail safe values that we can use if a RenderCommand
283 // is missing a shader
284 RenderStateSet *m_defaultRenderStateSet;
285 ShaderParameterPack m_defaultUniformPack;
286
287 QScopedPointer<SubmissionContext> m_submissionContext;
288 QSurfaceFormat m_format;
289
290 RenderQueue<RenderView> m_renderQueue;
291 QScopedPointer<VSyncFrameAdvanceService> m_vsyncFrameAdvanceService;
292
293 QSemaphore m_submitRenderViewsSemaphore;
294 QSemaphore m_waitForInitializationToBeCompleted;
295 QMutex m_hasBeenInitializedMutex;
296
297 QAtomicInt m_running;
298
299 std::vector<Attribute *> m_dirtyAttributes;
300 std::vector<Geometry *> m_dirtyGeometry;
301 QAtomicInt m_exposed;
302
303 struct DirtyBits {
304 BackendNodeDirtySet marked; // marked dirty since last job build
305 BackendNodeDirtySet remaining; // remaining dirty after jobs have finished
306 };
307 DirtyBits m_dirtyBits;
308
309 QAtomicInt m_lastFrameCorrect;
310 QOpenGLContext *m_glContext;
311 QOpenGLContext *m_shareContext;
312 mutable QMutex m_shareContextMutex;
313
314 qint64 m_time;
315
316 RenderSettings *m_settings;
317
318 UpdateShaderDataTransformJobPtr m_updateShaderDataTransformJob;
319 FrameCleanupJobPtr m_cleanupJob;
320 SendBufferCaptureJobPtr m_sendBufferCaptureJob;
321 FilterCompatibleTechniqueJobPtr m_filterCompatibleTechniqueJob;
322 LightGathererPtr m_lightGathererJob;
323 RenderableEntityFilterPtr m_renderableEntityFilterJob;
324 ComputableEntityFilterPtr m_computableEntityFilterJob;
325
326 QMutex m_pendingRenderCaptureSendRequestsMutex;
327 std::vector<Qt3DCore::QNodeId> m_pendingRenderCaptureSendRequests;
328
329 void performDraw(const RenderCommand *command);
330 void performCompute(const RenderView *rv, RenderCommand *command);
331 void createOrUpdateVAO(RenderCommand *command,
332 HVao *previousVAOHandle,
333 OpenGLVertexArrayObject **vao);
334
335 SynchronizerJobPtr m_bufferGathererJob;
336 SynchronizerJobPtr m_vaoGathererJob;
337 SynchronizerJobPtr m_textureGathererJob;
338 SynchronizerPostFramePtr m_introspectShaderJob;
339
340 void lookForAbandonedVaos();
341 void lookForDirtyBuffers();
342 void lookForDownloadableBuffers();
343 void lookForDirtyTextures();
344 void reloadDirtyShaders();
345 void sendShaderChangesToFrontend(Qt3DCore::QAspectManager *manager);
346 void sendTextureChangesToFrontend(Qt3DCore::QAspectManager *manager);
347 void sendSetFenceHandlesToFrontend(Qt3DCore::QAspectManager *manager);
348 void sendDisablesToFrontend(Qt3DCore::QAspectManager *manager);
349
350 QMutex m_abandonedVaosMutex;
351 std::vector<HVao> m_abandonedVaos;
352
353 std::vector<HBuffer> m_dirtyBuffers;
354 std::vector<Qt3DCore::QNodeId> m_downloadableBuffers;
355 std::vector<HShader> m_dirtyShaders;
356 std::vector<HTexture> m_dirtyTextures;
357 std::vector<QPair<Texture::TextureUpdateInfo, Qt3DCore::QNodeIdVector>> m_updatedTextureProperties;
358 std::vector<QPair<Qt3DCore::QNodeId, GLFence>> m_updatedSetFences;
359 std::vector<Qt3DCore::QNodeId> m_updatedDisableSubtreeEnablers;
360 Qt3DCore::QNodeIdVector m_textureIdsToCleanup;
361 std::vector<ShaderBuilderUpdate> m_shaderBuilderUpdates;
362 Qt3DCore::QNodeIdVector m_lastLoadedShaderIds;
363
364 bool m_ownedContext;
365
366 OffscreenSurfaceHelper *m_offscreenHelper;
367 GLResourceManagers *m_glResourceManagers;
368 QMutex m_offscreenSurfaceMutex;
369
370 QScopedPointer<Qt3DRender::Debug::CommandExecuter> m_commandExecuter;
371
372 mutable QScopedPointer<Qt3DRender::Render::Profiling::FrameProfiler> m_frameProfiler;
373
374#ifdef QT_BUILD_INTERNAL
375 friend class ::tst_Renderer;
376#endif
377
378 QMetaObject::Connection m_contextConnection;
379 RendererCache<RenderCommand> m_cache;
380 bool m_shouldSwapBuffers;
381 RenderDriver m_driver = RenderDriver::Qt3D;
382
383 std::vector<FrameGraphNode *> m_frameGraphLeaves;
384 QScreen *m_screen = nullptr;
385 QSharedPointer<ResourceAccessor> m_scene2DResourceAccessor;
386
387 Debug::ImGuiRenderer *m_imGuiRenderer;
388 int m_jobsInLastFrame;
389};
390
391} // namespace OpenGL
392} // namespace Render
393} // namespace Qt3DRender
394
395QT_END_NAMESPACE
396
397#endif // QT3DRENDER_RENDER_OPENGL_RENDERER_H
398

source code of qt3d/src/plugins/renderers/opengl/renderer/renderer_p.h