diff options
Diffstat (limited to 'src/plugins/renderers/opengl/renderer/renderer_p.h')
-rw-r--r-- | src/plugins/renderers/opengl/renderer/renderer_p.h | 464 |
1 files changed, 464 insertions, 0 deletions
diff --git a/src/plugins/renderers/opengl/renderer/renderer_p.h b/src/plugins/renderers/opengl/renderer/renderer_p.h new file mode 100644 index 000000000..eac622192 --- /dev/null +++ b/src/plugins/renderers/opengl/renderer/renderer_p.h @@ -0,0 +1,464 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB). +** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DRENDER_RENDER_RENDERER_H +#define QT3DRENDER_RENDER_RENDERER_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DRender/qrenderaspect.h> +#include <Qt3DRender/qtechnique.h> +#include <Qt3DRender/private/handle_types_p.h> +#include <Qt3DRender/private/abstractrenderer_p.h> +#include <Qt3DCore/qaspectjob.h> +#include <Qt3DRender/private/qt3drender_global_p.h> +#include <Qt3DRender/private/pickboundingvolumejob_p.h> +#include <Qt3DRender/private/raycastingjob_p.h> +#include <Qt3DRender/private/rendersettings_p.h> +#include <Qt3DRender/private/expandboundingvolumejob_p.h> +#include <Qt3DRender/private/updateworldtransformjob_p.h> +#include <Qt3DRender/private/calcboundingvolumejob_p.h> +#include <Qt3DRender/private/updateshaderdatatransformjob_p.h> +#include <Qt3DRender/private/framecleanupjob_p.h> +#include <Qt3DRender/private/updateworldboundingvolumejob_p.h> +#include <Qt3DRender/private/updatetreeenabledjob_p.h> +#include <Qt3DRender/private/platformsurfacefilter_p.h> +#include <Qt3DRender/private/sendbuffercapturejob_p.h> +#include <Qt3DRender/private/genericlambdajob_p.h> +#include <Qt3DRender/private/updatemeshtrianglelistjob_p.h> +#include <Qt3DRender/private/updateskinningpalettejob_p.h> +#include <Qt3DRender/private/updateentitylayersjob_p.h> +#include <Qt3DRender/private/shaderbuilder_p.h> +#include <Qt3DRender/private/lightgatherer_p.h> +#include <Qt3DRender/private/texture_p.h> +#include <shaderparameterpack_p.h> +#include <renderviewinitializerjob_p.h> +#include <filtercompatibletechniquejob_p.h> +#include <renderercache_p.h> +#include <logging_p.h> +#include <gl_handle_types_p.h> +#include <glfence_p.h> +#include <renderercache_p.h> + +#include <QHash> +#include <QMatrix4x4> +#include <QObject> + +#include <QOpenGLShaderProgram> +#include <QOpenGLVertexArrayObject> +#include <QOpenGLBuffer> +#include <QMutex> +#include <QWaitCondition> +#include <QAtomicInt> +#include <QScopedPointer> +#include <QSemaphore> + +#include <functional> + +#if defined(QT_BUILD_INTERNAL) +class tst_Renderer; +#endif + +QT_BEGIN_NAMESPACE + +class QSurface; +class QMouseEvent; +class QScreen; + +namespace Qt3DCore { +class QEntity; +class QFrameAllocator; +class QEventFilterService; +} + +namespace Qt3DRender { + +class QCamera; +class QMaterial; +class QShaderProgram; +class QMesh; +class QRenderPass; +class QAbstractShapeMesh; +struct GraphicsApiFilterData; +class QSceneImporter; + +namespace Debug { +class CommandExecuter; +} + +namespace Render { + +class CameraLens; +class SubmissionContext; +class FrameGraphNode; +class Material; +class Technique; +class Shader; +class Entity; +class RenderCommand; +class RenderQueue; +class RenderView; +class Effect; +class RenderPass; +class RenderThread; +class RenderStateSet; +class VSyncFrameAdvanceService; +class PickEventFilter; +class NodeManagers; +class GLResourceManagers; +class GLShader; +class ResourceAccessor; + +class UpdateLevelOfDetailJob; +typedef QSharedPointer<UpdateLevelOfDetailJob> UpdateLevelOfDetailJobPtr; + +using SynchronizerJobPtr = GenericLambdaJobPtr<std::function<void()>>; +using SynchronizerPostFramePtr = GenericLambdaJobAndPostFramePtr<std::function<void ()>, std::function<void (Qt3DCore::QAspectManager *)>>; + +template<typename T, typename ... Ts> +class FilterEntityByComponentJob; +template<typename T, typename ... Ts> +using FilterEntityByComponentJobPtr = QSharedPointer<FilterEntityByComponentJob<T, Ts...>>; +using ComputableEntityFilterPtr = FilterEntityByComponentJobPtr<Render::ComputeCommand, Render::Material>; +using RenderableEntityFilterPtr = FilterEntityByComponentJobPtr<Render::GeometryRenderer, Render::Material>; + +class Q_3DRENDERSHARED_PRIVATE_EXPORT Renderer : public AbstractRenderer +{ +public: + explicit Renderer(QRenderAspect::RenderType type); + ~Renderer(); + + void dumpInfo() const override; + API api() const override { return AbstractRenderer::OpenGL; } + + qint64 time() const override; + void setTime(qint64 time) override; + + void setNodeManagers(NodeManagers *managers) override; + void setServices(Qt3DCore::QServiceLocator *services) override; + void setSurfaceExposed(bool exposed) override; + + NodeManagers *nodeManagers() const override; + Qt3DCore::QServiceLocator *services() const override { return m_services; } + + void initialize() override; + void shutdown() override; + void releaseGraphicsResources() override; + + void render() override; + void doRender(bool swapBuffers = true) override; + void cleanGraphicsResources() override; + + bool isRunning() const override { return m_running.loadRelaxed(); } + + void setSceneRoot(Entity *sgRoot) override; + Entity *sceneRoot() const override { return m_renderSceneRoot; } + + FrameGraphNode *frameGraphRoot() const override; + RenderQueue *renderQueue() const { return m_renderQueue; } + + void markDirty(BackendNodeDirtySet changes, BackendNode *node) override; + BackendNodeDirtySet dirtyBits() override; + +#if defined(QT_BUILD_INTERNAL) + void clearDirtyBits(BackendNodeDirtySet changes) override; +#endif + bool shouldRender() const override; + void skipNextFrame() override; + void jobsDone(Qt3DCore::QAspectManager *manager) override; + + QVector<Qt3DCore::QAspectJobPtr> preRenderingJobs() override; + QVector<Qt3DCore::QAspectJobPtr> renderBinJobs() override; + Qt3DCore::QAspectJobPtr pickBoundingVolumeJob() override; + Qt3DCore::QAspectJobPtr rayCastingJob() override; + Qt3DCore::QAspectJobPtr syncLoadingJobs() override; + Qt3DCore::QAspectJobPtr expandBoundingVolumeJob() override; + + QVector<Qt3DCore::QAspectJobPtr> createRenderBufferJobs() const; + + inline FrameCleanupJobPtr frameCleanupJob() const { return m_cleanupJob; } + inline UpdateShaderDataTransformJobPtr updateShaderDataTransformJob() const { return m_updateShaderDataTransformJob; } + inline CalculateBoundingVolumeJobPtr calculateBoundingVolumeJob() const { return m_calculateBoundingVolumeJob; } + inline UpdateTreeEnabledJobPtr updateTreeEnabledJob() const { return m_updateTreeEnabledJob; } + inline UpdateWorldTransformJobPtr updateWorldTransformJob() const { return m_worldTransformJob; } + inline UpdateWorldBoundingVolumeJobPtr updateWorldBoundingVolumeJob() const { return m_updateWorldBoundingVolumeJob; } + inline UpdateLevelOfDetailJobPtr updateLevelOfDetailJob() const { return m_updateLevelOfDetailJob; } + inline UpdateMeshTriangleListJobPtr updateMeshTriangleListJob() const { return m_updateMeshTriangleListJob; } + inline FilterCompatibleTechniqueJobPtr filterCompatibleTechniqueJob() const { return m_filterCompatibleTechniqueJob; } + inline SynchronizerJobPtr syncLoadingJobs() const { return m_syncLoadingJobs; } + inline UpdateSkinningPaletteJobPtr updateSkinningPaletteJob() const { return m_updateSkinningPaletteJob; } + inline SynchronizerPostFramePtr introspectShadersJob() const { return m_introspectShaderJob; } + inline Qt3DCore::QAspectJobPtr bufferGathererJob() const { return m_bufferGathererJob; } + inline Qt3DCore::QAspectJobPtr textureGathererJob() const { return m_textureGathererJob; } + inline UpdateEntityLayersJobPtr updateEntityLayersJob() const { return m_updateEntityLayersJob; } + inline LightGathererPtr lightGathererJob() const { return m_lightGathererJob; } + inline RenderableEntityFilterPtr renderableEntityFilterJob() const { return m_renderableEntityFilterJob; } + inline ComputableEntityFilterPtr computableEntityFilterJob() const { return m_computableEntityFilterJob; } + inline SynchronizerJobPtr cacheLightJob() const { return m_cacheLightsJob; } + inline SynchronizerJobPtr cacheRenderableEntitiesJob() const { return m_cacheRenderableEntitiesJob; } + inline SynchronizerJobPtr cacheComputableEntitiesJob() const { return m_cacheComputableEntitiesJob; } + + Qt3DCore::QAbstractFrameAdvanceService *frameAdvanceService() const override; + + void registerEventFilter(Qt3DCore::QEventFilterService *service) override; + + void setSettings(RenderSettings *settings) override; + RenderSettings *settings() const override; + QOpenGLContext *shareContext() const override; + + inline GLResourceManagers *glResourceManagers() const { return m_glResourceManagers; } + + // Executed in secondary GL thread + void loadShader(Shader *shader, Qt3DRender::Render::HShader shaderHandle) override; + + + void updateGLResources(); + void updateTexture(Texture *texture); + void cleanupTexture(Qt3DCore::QNodeId cleanedUpTextureId); + void cleanupShader(const Shader *shader); + void downloadGLBuffers(); + void blitFramebuffer(Qt3DCore::QNodeId inputRenderTargetId, + Qt3DCore::QNodeId outputRenderTargetId, + QRect inputRect, + QRect outputRect, + GLuint defaultFramebuffer); + + void prepareCommandsSubmission(const QVector<RenderView *> &renderViews); + bool executeCommandsSubmission(const RenderView *rv); + bool updateVAOWithAttributes(Geometry *geometry, + const RenderCommand *command, + GLShader *shader, + bool forceUpdate); + + bool requiresVAOAttributeUpdate(Geometry *geometry, + const RenderCommand *command) const; + + // For Scene2D rendering + void setOpenGLContext(QOpenGLContext *context) override; + bool accessOpenGLTexture(Qt3DCore::QNodeId nodeId, + QOpenGLTexture **texture, + QMutex **lock, + bool readonly) override; + QSharedPointer<RenderBackendResourceAccessor> resourceAccessor() const override; + + + const GraphicsApiFilterData *contextInfo() const; + SubmissionContext *submissionContext() const; + + inline RenderStateSet *defaultRenderState() const { return m_defaultRenderStateSet; } + + QList<QPair<QObject*, QMouseEvent>> pendingPickingEvents() const; + QList<QKeyEvent> pendingKeyEvents() const; + + void enqueueRenderView(RenderView *renderView, int submitOrder); + bool isReadyToSubmit(); + + QVariant executeCommand(const QStringList &args) override; + void setOffscreenSurfaceHelper(OffscreenSurfaceHelper *helper) override; + QSurfaceFormat format() override; + + struct ViewSubmissionResultData + { + ViewSubmissionResultData() + : lastBoundFBOId(0) + , surface(nullptr) + {} + + uint lastBoundFBOId; + QSurface *surface; + }; + + ViewSubmissionResultData submitRenderViews(const QVector<Render::RenderView *> &renderViews); + + RendererCache *cache() { return &m_cache; } + void setScreen(QScreen *scr) override; + QScreen *screen() const override; + +#ifdef QT3D_RENDER_UNIT_TESTS +public: +#else + +private: +#endif + bool canRender() const; + + Qt3DCore::QServiceLocator *m_services; + NodeManagers *m_nodesManager; + + // Frame graph root + Qt3DCore::QNodeId m_frameGraphRootUuid; + + Entity *m_renderSceneRoot; + + // Fail safe values that we can use if a RenderCommand + // is missing a shader + RenderStateSet *m_defaultRenderStateSet; + ShaderParameterPack m_defaultUniformPack; + + QScopedPointer<SubmissionContext> m_submissionContext; + QSurfaceFormat m_format; + + RenderQueue *m_renderQueue; + QScopedPointer<RenderThread> m_renderThread; + QScopedPointer<VSyncFrameAdvanceService> m_vsyncFrameAdvanceService; + + QSemaphore m_submitRenderViewsSemaphore; + QSemaphore m_waitForInitializationToBeCompleted; + QMutex m_hasBeenInitializedMutex; + + QAtomicInt m_running; + + QScopedPointer<PickEventFilter> m_pickEventFilter; + + QVector<Attribute *> m_dirtyAttributes; + QVector<Geometry *> m_dirtyGeometry; + QAtomicInt m_exposed; + + struct DirtyBits { + BackendNodeDirtySet marked; // marked dirty since last job build + BackendNodeDirtySet remaining; // remaining dirty after jobs have finished + }; + DirtyBits m_dirtyBits; + + QAtomicInt m_lastFrameCorrect; + QOpenGLContext *m_glContext; + QOpenGLContext *m_shareContext; + mutable QMutex m_shareContextMutex; + PickBoundingVolumeJobPtr m_pickBoundingVolumeJob; + RayCastingJobPtr m_rayCastingJob; + + qint64 m_time; + + RenderSettings *m_settings; + + UpdateShaderDataTransformJobPtr m_updateShaderDataTransformJob; + FrameCleanupJobPtr m_cleanupJob; + UpdateWorldTransformJobPtr m_worldTransformJob; + ExpandBoundingVolumeJobPtr m_expandBoundingVolumeJob; + CalculateBoundingVolumeJobPtr m_calculateBoundingVolumeJob; + UpdateWorldBoundingVolumeJobPtr m_updateWorldBoundingVolumeJob; + UpdateTreeEnabledJobPtr m_updateTreeEnabledJob; + SendBufferCaptureJobPtr m_sendBufferCaptureJob; + UpdateSkinningPaletteJobPtr m_updateSkinningPaletteJob; + UpdateLevelOfDetailJobPtr m_updateLevelOfDetailJob; + UpdateMeshTriangleListJobPtr m_updateMeshTriangleListJob; + FilterCompatibleTechniqueJobPtr m_filterCompatibleTechniqueJob; + UpdateEntityLayersJobPtr m_updateEntityLayersJob; + LightGathererPtr m_lightGathererJob; + RenderableEntityFilterPtr m_renderableEntityFilterJob; + ComputableEntityFilterPtr m_computableEntityFilterJob; + + QVector<Qt3DCore::QNodeId> m_pendingRenderCaptureSendRequests; + + void performDraw(RenderCommand *command); + void performCompute(const RenderView *rv, RenderCommand *command); + void createOrUpdateVAO(RenderCommand *command, + HVao *previousVAOHandle, + OpenGLVertexArrayObject **vao); + + SynchronizerJobPtr m_bufferGathererJob; + SynchronizerJobPtr m_vaoGathererJob; + SynchronizerJobPtr m_textureGathererJob; + SynchronizerJobPtr m_sendSetFenceHandlesToFrontendJob; + SynchronizerPostFramePtr m_introspectShaderJob; + SynchronizerJobPtr m_syncLoadingJobs; + SynchronizerJobPtr m_cacheRenderableEntitiesJob; + SynchronizerJobPtr m_cacheComputableEntitiesJob; + SynchronizerJobPtr m_cacheLightsJob; + + void lookForAbandonedVaos(); + void lookForDirtyBuffers(); + void lookForDownloadableBuffers(); + void lookForDirtyTextures(); + void reloadDirtyShaders(); + void sendShaderChangesToFrontend(Qt3DCore::QAspectManager *manager); + void sendTextureChangesToFrontend(Qt3DCore::QAspectManager *manager); + void sendSetFenceHandlesToFrontend(); + void sendDisablesToFrontend(Qt3DCore::QAspectManager *manager); + + QMutex m_abandonedVaosMutex; + QVector<HVao> m_abandonedVaos; + + QVector<HBuffer> m_dirtyBuffers; + QVector<Qt3DCore::QNodeId> m_downloadableBuffers; + QVector<HShader> m_dirtyShaders; + QVector<HTexture> m_dirtyTextures; + QVector<QPair<Texture::TextureUpdateInfo, Qt3DCore::QNodeIdVector>> m_updatedTextureProperties; + QVector<QPair<Qt3DCore::QNodeId, GLFence>> m_updatedSetFences; + QVector<Qt3DCore::QNodeId> m_updatedDisableSubtreeEnablers; + Qt3DCore::QNodeIdVector m_textureIdsToCleanup; + QVector<ShaderBuilderUpdate> m_shaderBuilderUpdates; + + bool m_ownedContext; + + OffscreenSurfaceHelper *m_offscreenHelper; + GLResourceManagers *m_glResourceManagers; + QMutex m_offscreenSurfaceMutex; + + QScopedPointer<Qt3DRender::Debug::CommandExecuter> m_commandExecuter; + +#ifdef QT_BUILD_INTERNAL + friend class ::tst_Renderer; +#endif + + QMetaObject::Connection m_contextConnection; + RendererCache m_cache; + bool m_shouldSwapBuffers; + + QVector<FrameGraphNode *> m_frameGraphLeaves; + QScreen *m_screen = nullptr; + QSharedPointer<ResourceAccessor> m_scene2DResourceAccessor; +}; + +} // namespace Render +} // namespace Qt3DRender + +QT_END_NAMESPACE + +#endif // QT3DRENDER_RENDER_RENDERER_H |