Revision control
++ // Copyright (C) 2008-2012 NVIDIA Corporation.
++ // Copyright (C) 2019 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
++ // Qt-Security score:significant reason:default
++
++
++ #ifndef QSSG_RENDERER_P_H
++ #define QSSG_RENDERER_P_H
++
++ //
++ // W A R N I N G
++ // -------------
++ //
++ // This file is not part of the Qt API. It exists purely as an
++ // implementation detail. This header file may change from version to
++ // version without notice, or even be removed.
++ //
++ // We mean it.
++ //
++
++ #include <private/qssgrenderpickresult_p.h>
++ #include <private/qssgrhicontext_p.h>
++ #include <private/qssgrhiquadrenderer_p.h>
++
++ #include <QtCore/qpointer.h>
++
++ #include <vector>
++
++ QT_BEGIN_NAMESPACE
++
++ class QSSGShaderCache;
++ class QSSGProgramGenerator;
++ class QSSGShaderLibraryManager;
++ class QSSGBufferManager;
++ class QSSGLayerRenderData;
++ class QSSGRenderContextInterface;
++ struct QSSGRenderNode;
++ struct QSSGRenderItem2D;
++ struct QSSGRenderRay;
++ class QSSGSubsetRenderable;
++ struct QSSGShaderDefaultMaterialKeyProperties;
++ struct QSSGShaderFeatures;
++ class QSSGRenderItem2DData;
++ class QSGRenderContext;
++ class QSSGFrustum;
++ class QSSGUserShaderAugmentation;
++
++ class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRenderer
++ {
++ Q_DISABLE_COPY(QSSGRenderer)
++ public:
++ QSSGRenderer();
++ ~QSSGRenderer();
++
++ // Returns true if this layer or a sibling was dirty.
++ bool prepareLayerForRender(QSSGRenderLayer &inLayer);
++
++ void rhiPrepare(QSSGRenderLayer &inLayer);
++ void rhiRender(QSSGRenderLayer &inLayer);
++
++ // Clients need to call this every frame in order for various subsystems to release
++ // temporary per-frame allocated objects.
++ void beginFrame(QSSGRenderLayer &layer, bool allowRecursion = true);
++
++ // When allowRecursion is true, the cleanup is only done when all
++ // beginFrames got their corresponding endFrame. This is indicated by the
++ // return value (false if nothing's been done due to pending "frames")
++ bool endFrame(QSSGRenderLayer &layer, bool allowRecursion = true);
++
++ // Get the number of times EndFrame has been called
++ [[nodiscard]] constexpr quint32 frameCount() const { return m_frameCount; }
++
++ void setViewport(QRect inViewport) { m_viewport = inViewport; }
++ QRect viewport() const { return m_viewport; }
++
++ void setDpr(float dpr) { m_dpr = dpr; }
++ float dpr() const { return m_dpr; }
++
++ void setScissorRect(QRect inScissorRect) { m_scissorRect = inScissorRect; }
++ QRect scissorRect() const { return m_scissorRect; }
++
++ quint32 frameDepth() const { return m_activeFrameRef; }
++
++ const std::unique_ptr<QSSGRhiQuadRenderer> &rhiQuadRenderer() const;
++ const std::unique_ptr<QSSGRhiCubeRenderer> &rhiCubeRenderer() const;
++
++ QSSGRenderContextInterface *contextInterface() const { return m_contextInterface; }
++
++ // Before we start rendering a sublayer(s), e.g., Item2D with View3Ds,
++ // we need to inform the renderer about it, so we can restore the state as we
++ // return from the sublayer(s) rendering. The state will be saved in the data set
++ // for the layer.
++ void beginSubLayerRender(QSSGLayerRenderData &inLayer);
++ void endSubLayerRender(QSSGLayerRenderData &inLayer);
++
++ void releaseItem2DData(const QSSGRenderItem2D &item2D);
++
++ protected:
++ void cleanupResources(QList<QSSGRenderGraphObject*> &resources);
++ void cleanupResources(QSet<QSSGRenderGraphObject*> &resources);
++
++ private:
++ friend class QSSGRendererPrivate;
++ friend class QSSGLayerRenderData;
++ friend class QSSGRenderContextInterface;
++ friend class QQuick3DSceneRenderer;
++ friend class QQuick3DWindowAttachment;
++ friend class QSSGCleanupObject;
++ friend class QSSGParticleRenderer;
++
++ QSSGLayerRenderData *getOrCreateLayerRenderData(QSSGRenderLayer &layer);
++ void beginLayerRender(QSSGLayerRenderData &inLayer);
++ void endLayerRender();
++ void addMaterialDirtyClear(QSSGRenderGraphObject *material);
++ void cleanupUnreferencedBuffers(QSSGRenderLayer *inLayer);
++ void resetResourceCounters(QSSGRenderLayer *inLayer);
++ void releaseCachedResources();
++
++ void registerItem2DData(QSSGRenderItem2DData &data);
++ void unregisterItem2DData(QSSGRenderItem2DData &data);
++
++ QSSGRenderContextInterface *m_contextInterface = nullptr; // We're own by the context interface
++
++ bool m_globalPickingEnabled = false;
++
++ // Temporary information stored only when rendering a particular layer.
++ QSSGLayerRenderData *m_currentLayer = nullptr;
++
++ QSet<QSSGRenderGraphObject *> m_materialClearDirty;
++
++ QPointer<QSGRenderContext> m_qsgRenderContext;
++
++ // Item2D data (per layer).
++ // Note that the data is own by the layer.
++ std::vector<QSSGRenderItem2DData *> m_item2DDatas;
++
++ mutable std::unique_ptr<QSSGRhiQuadRenderer> m_rhiQuadRenderer;
++ mutable std::unique_ptr<QSSGRhiCubeRenderer> m_rhiCubeRenderer;
++
++ quint32 m_activeFrameRef = 0;
++ quint32 m_frameCount = 0;
++
++ // Viewport that this render context should use
++ QRect m_viewport;
++ float m_dpr = 1.0;
++ QRect m_scissorRect;
++ };
++
++ class Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRendererPrivate
++ {
++ QSSGRendererPrivate() = default;
++ public:
++ using PickResultList = QVarLengthArray<QSSGRenderPickResult, 20>; // Lets assume most items are filtered out already
++
++ static QSSGRhiShaderPipelinePtr generateRhiShaderPipelineImpl(QSSGSubsetRenderable &renderable,
++ QSSGShaderLibraryManager &shaderLibraryManager,
++ QSSGShaderCache &shaderCache,
++ QSSGProgramGenerator &shaderProgramGenerator,
++ const QSSGShaderDefaultMaterialKeyProperties &shaderKeyProperties,
++ const QSSGShaderFeatures &featureSet,
++ const QSSGUserShaderAugmentation &shaderAugmentation,
++ QByteArray &shaderString);
++ static QSSGRhiShaderPipelinePtr generateRhiShaderPipeline(QSSGRenderer &renderer,
++ QSSGSubsetRenderable &inRenderable,
++ const QSSGShaderFeatures &inFeatureSet,
++ const QSSGUserShaderAugmentation &shaderAugmentation);
++
++ static QSSGRhiShaderPipelinePtr getShaderPipelineForDefaultMaterial(QSSGRenderer &renderer,
++ QSSGSubsetRenderable &inRenderable,
++ const QSSGShaderFeatures &inFeatureSet,
++ const QSSGUserShaderAugmentation &shaderAugmentation);
++
++ static void getLayerHitObjectList(const QSSGRenderLayer &layer,
++ QSSGBufferManager &bufferManager,
++ const QSSGRenderRay &ray,
++ bool inPickEverything,
++ PickResultList &outIntersectionResult);
++ static void intersectRayWithSubsetRenderable(const QSSGRenderLayer &layer, QSSGBufferManager &bufferManager,
++ const QSSGRenderRay &inRay,
++ const QSSGRenderNode &node,
++ PickResultList &outIntersectionResultList);
++ static void intersectRayWithItem2D(const QSSGRenderLayer &layer, const QSSGRenderRay &inRay,
++ const QSSGRenderItem2D &item2D,
++ PickResultList &outIntersectionResultList);
++
++ static std::optional<QSSGRenderPickResult> closestPointOnSubsetRenderable(const QSSGRenderLayer &layer,
++ QSSGBufferManager &bufferManager,
++ const QVector3D ¢er,
++ float radiusSquared,
++ const QSSGRenderNode &node);
++
++ static PickResultList syncPickAll(const QSSGRenderContextInterface &ctx,
++ const QSSGRenderLayer &layer,
++ const QSSGRenderRay &ray);
++
++ static PickResultList syncPick(const QSSGRenderContextInterface &ctx,
++ const QSSGRenderLayer &layer,
++ const QSSGRenderRay &ray,
++ QSSGRenderNode *target = nullptr);
++
++ static PickResultList syncPickSubset(const QSSGRenderLayer &layer,
++ QSSGBufferManager &bufferManager,
++ const QSSGRenderRay &ray,
++ QVarLengthArray<QSSGRenderNode *> subset);
++
++ static std::optional<QSSGRenderPickResult> syncPickClosestPoint(const QSSGRenderContextInterface &ctx,
++ const QSSGRenderLayer &layer,
++ const QVector3D ¢er,
++ const float radiusSquared,
++ QSSGRenderNode *target = nullptr);
++
++ static QList<const QSSGRenderNode *> syncPickInFrustum(const QSSGRenderContextInterface &ctx,
++ const QSSGRenderLayer &layer,
++ const QSSGFrustum &frustum);
++
++ // Setting this true enables picking for all the models, regardless of
++ // the models pickable property.
++ static bool isGlobalPickingEnabled(const QSSGRenderer &renderer) { return renderer.m_globalPickingEnabled; }
++ static void setGlobalPickingEnabled(QSSGRenderer &renderer, bool isEnabled);
++
++ static void setRenderContextInterface(QSSGRenderer &renderer, QSSGRenderContextInterface *ctx);
++ static void setSgRenderContext(QSSGRenderer &renderer, QSGRenderContext *sgRenderCtx);
++
++ static QSSGLayerRenderData *getCurrentRenderData(const QSSGRenderer &renderer) { return renderer.m_currentLayer; }
++
++ static QSGRenderContext *getSgRenderContext(const QSSGRenderer &renderer);
++
++ static constexpr float minimumRenderOpacity = .01f;
++ };
++
++ QT_END_NAMESPACE
++
++ #endif // QSSG_RENDERER_P_H