6#ifndef QSGBATCHRENDERER_P_H
7#define QSGBATCHRENDERER_P_H
20#include <private/qsgrenderer_p.h>
21#include <private/qsgdefaultrendercontext_p.h>
22#include <private/qsgnodeupdater_p.h>
23#include <private/qsgrendernode_p.h>
24#include <private/qdatabuffer_p.h>
25#include <private/qsgtexture_p.h>
27#include <QtCore/QBitArray>
28#include <QtCore/QStack>
37#define QSG_RENDERER_COORD_LIMIT 1000000.0f
70 for (
int i=0;
i<PageSize; ++
i)
88template <
typename Type,
int PageSize>
class Allocator
93 pages.push_back(
new AllocatorPage<Type, PageSize>());
103 AllocatorPage<Type, PageSize> *
p = 0;
105 if (
pages.at(
i)->available > 0) {
117 p =
new AllocatorPage<Type, PageSize>();
121 uint pos =
p->blocks[PageSize -
p->available];
122 void *mem =
p->at(
pos);
124 p->allocated.setBit(
pos);
131 AllocatorPage<Type, PageSize> *
page =
pages.at(pageIndex);
133 qFatal(
"Double delete in allocator: page=%d, index=%d", pageIndex ,
index);
137 memset(mem, 0,
sizeof(
Type));
159 for (
int i=0;
i<
pages.size(); ++
i) {
160 AllocatorPage<Type, PageSize> *
p =
pages.at(
i);
161 if ((
Type *) (&
p->data[0]) <=
t && (
Type *) (&
p->data[PageSize *
sizeof(
Type)]) >
t) {
168 AllocatorPage<Type, PageSize> *
page =
pages.at(pageIndex);
174 QVector<AllocatorPage<Type, PageSize> *>
pages;
190 const float *
m = mat.constData();
191 r.
x =
x *
m[0] +
y *
m[4] +
m[12];
192 r.y =
x *
m[1] +
y *
m[5] +
m[13];
204 d <<
"Pt(" <<
p.x <<
p.y <<
")";
243 bool xOverlap =
r.tl.x <
br.
x &&
r.br.x >
tl.
x;
244 bool yOverlap =
r.tl.y <
br.
y &&
r.br.y >
tl.
y;
245 return xOverlap && yOverlap;
257 d <<
"Rect(" <<
r.tl.x <<
r.tl.y <<
r.br.x <<
r.br.y <<
")";
382 bool updateStencilBuffer =
false;
408 void cleanupRemovedElements();
410 bool isTranslateOnlyToRoot()
const;
411 bool isSafeToBatch()
const;
423 positionAttribute = -1;
424 uploadedThisFrame =
false;
425 isRenderNode =
false;
426 ubufDataValid =
false;
489 child->m_next = m_child;
491 child->setParent(
this);
502 if (m_child ==
child)
503 m_child =
child->m_next;
507 child->m_next =
nullptr;
508 child->m_prev =
nullptr;
509 child->setParent(
nullptr);
520 Q_ASSERT(m_parent ==
nullptr ||
p ==
nullptr);
568 void visitOpacityNode(
Node *
n);
569 void visitTransformNode(
Node *
n);
570 void visitGeometryNode(
Node *
n);
571 void visitClipNode(
Node *
n);
575 void updateStates(
QSGNode *
n)
override;
576 void visitNode(
Node *
n);
582 QDataBuffer<Node *> m_roots;
583 QDataBuffer<QMatrix4x4> m_rootMatrices;
586 int m_transformChange;
594 bool depthTest =
false;
595 bool depthWrite =
false;
597 bool blending =
false;
604 QRhiGraphicsPipeline::ColorMask colorWrite = QRhiGraphicsPipeline::ColorMask(0xF);
606 bool usesScissor =
false;
607 bool stencilTest =
false;
610 float lineWidth = 1.0f;
612 int multiViewCount = 0;
638 return {
state, sms, rtDesc, srbDesc, {
qHash(rtDesc),
qHash(srbDesc) } };
642bool operator==(
const GraphicsPipelineStateKey &
a,
const GraphicsPipelineStateKey &
b)
noexcept;
643bool operator!=(
const GraphicsPipelineStateKey &
a,
const GraphicsPipelineStateKey &
b)
noexcept;
644size_t qHash(
const GraphicsPipelineStateKey &k,
size_t seed = 0) noexcept;
660 delete materialShader;
664 QVarLengthArray<QRhiShaderStage, 2>
stages;
680 void clearCachedRendererData();
694 int multiViewCount = 0);
698 int multiViewCount = 0);
701 QHash<ShaderKey, Shader *> rewrittenShaders;
702 QHash<ShaderKey, Shader *> stockShaders;
733 virtual void visualizeChangesPrepare(
Node *
n,
uint parentChanges = 0);
752 void nodeChanged(
QSGNode *node, QSGNode::DirtyState
state)
override;
754 void prepareInline()
override;
755 void renderInline()
override;
756 void releaseCachedResources()
override;
789 BuildRenderListsForTaggedRoots = 0x0001,
790 BuildRenderLists = 0x0002,
791 BuildBatches = 0x0004,
798 void destroyGraphicsResources();
802 void buildRenderListsFromScratch();
803 void buildRenderListsForTaggedRoots();
804 void tagSubRoots(
Node *node);
805 void buildRenderLists(
QSGNode *node);
807 void deleteRemovedElements();
808 void cleanupBatches(QDataBuffer<Batch *> *batches);
809 void prepareOpaqueBatches();
810 bool checkOverlap(
int first,
int last,
const Rect &bounds);
811 void prepareAlphaBatches();
812 void invalidateBatchAndOverlappingRenderOrders(
Batch *batch);
814 void uploadBatch(
Batch *
b);
815 void uploadMergedElement(
Element *e,
int vaOffset,
char **
vertexData,
char **zData,
char **indexData,
void *iBasePtr,
int *indexCount);
829 ClipState::ClipType updateStencilClip(
const QSGClipNode *clip);
831 void applyClipStateToGraphicsState();
834 void enqueueStencilDraw(
const Batch *batch);
836 void renderRenderNode(
Batch *batch);
838 void renderRhiRenderNode(
const Batch *batch);
842 bool changeBatchRoot(
Node *node,
Node *newRoot);
843 void registerBatchRoot(
Node *childRoot,
Node *parentRoot);
844 void removeBatchRootFromParent(
Node *childRoot);
845 void nodeChangedBatchRoot(
Node *node,
Node *root);
846 void turnNodeIntoBatchRoot(
Node *node);
847 void nodeWasTransformed(
Node *node,
int *vertexCount);
848 void nodeWasRemoved(
Node *node);
849 void nodeWasAdded(
QSGNode *node,
Node *shadowParent);
853 inline Batch *newBatch();
854 void invalidateAndRecycleBatch(
Batch *
b);
855 void releaseElement(
Element *e,
bool inDestructor =
false);
858 bool hasVisualizationModeWithContinuousUpdate()
const override;
862 QSet<Node *> m_taggedRoots;
863 QDataBuffer<Element *> m_opaqueRenderList;
864 QDataBuffer<Element *> m_alphaRenderList;
865 int m_nextRenderOrder;
866 bool m_partialRebuild;
868 bool m_forceNoDepthBuffer;
870 QHash<QSGRenderNode *, RenderNodeElement *> m_renderNodeElements;
871 QDataBuffer<Batch *> m_opaqueBatches;
872 QDataBuffer<Batch *> m_alphaBatches;
873 QHash<QSGNode *, Node *> m_nodes;
875 QDataBuffer<Batch *> m_batchPool;
876 QDataBuffer<Element *> m_elementsToDelete;
877 QDataBuffer<Element *> m_tmpAlphaElements;
878 QDataBuffer<Element *> m_tmpOpaqueElements;
880 QDataBuffer<QRhiBuffer *> m_vboPool;
881 QDataBuffer<QRhiBuffer *> m_iboPool;
885#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
886 int m_renderOrderRebuildLower;
887 int m_renderOrderRebuildUpper;
890 int m_batchNodeThreshold;
891 int m_batchVertexThreshold;
892 int m_srbPoolThreshold;
902 QDataBuffer<char> m_vertexUploadPool;
903 QDataBuffer<char> m_indexUploadPool;
905 Allocator<Node, 256> m_nodeAllocator;
906 Allocator<Element, 64> m_elementAllocator;
910 uint m_ubufAlignment;
911 bool m_uint32IndexForRhi;
914 QStack<GraphicsState> m_gstateStack;
915 QHash<QSGSamplerDescription, QRhiSampler *> m_samplers;
918 struct StencilClipCommonData {
926 } m_stencilClipCommon;
928 inline int mergedIndexElemSize()
const;
929 inline bool useDepthBuffer()
const;
930 inline void setStateForDepthPostPass();
933Batch *Renderer::newBatch()
936 int size = m_batchPool.size();
938 b = m_batchPool.at(
size - 1);
940 m_batchPool.resize(
size - 1);
943 Q_ASSERT(offsetof(Batch, ibo) ==
sizeof(
Buffer) + offsetof(Batch, vbo));
944 memset(&
b->vbo, 0,
sizeof(
Buffer) * 2);
946 b->stencilClipState.reset();
953int Renderer::mergedIndexElemSize()
const
964bool Renderer::useDepthBuffer()
const
969void Renderer::setStateForDepthPostPass()
971 m_gstate.colorWrite = {};
972 m_gstate.depthWrite =
true;
973 m_gstate.depthTest =
true;
977void Renderer::StencilClipCommonData::reset()
998 updateStencilBuffer =
false;
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
char at(qsizetype i) const
Returns the byte at index position i in the byte array.
The QColor class provides colors based on RGB, HSV or CMYK values.
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
IndexFormat
Specifies the index data type.
BlendOp
Specifies the blend operation.
PolygonMode
Specifies the polygon rasterization mode.
BlendFactor
Specifies the blend factor.
CompareOp
Specifies the depth or stencil comparison function.
CullMode
Specifies the culling mode.
Topology
Specifies the primitive topology.
virtual QVector< quint32 > serializedFormat() const =0
QVector< quint32 > serializedLayoutDescription() const
const Type * at(uint index) const
QVector< AllocatorPage< Type, PageSize > * > pages
void releaseExplicit(uint pageIndex, uint index)
QMultiHash< QVector< quint32 >, QRhiShaderResourceBindings * > srbPool
QHash< GraphicsPipelineStateKey, QRhiGraphicsPipeline * > pipelineCache
ShaderManager(QSGDefaultRenderContext *ctx)
QVector< quint32 > srbLayoutDescSerializeWorkspace
void registerWithParentRoot(QSGNode *subRoot, QSGNode *parentRoot)
void updateRootTransforms(Node *n)
virtual void visualize()=0
void setMode(VisualizeMode mode)
virtual void prepareVisualize()=0
VisualizeMode mode() const
virtual void releaseResources()=0
QHash< Node *, uint > m_visualizeChangeSet
VisualizeMode m_visualizeMode
The QSGClipNode class implements the clipping functionality in the scene graph.
The QSGGeometryNode class is used for all rendered content in the scene graph.
The QSGGeometry class provides low-level storage for graphics primitives in the \l{Qt Quick Scene Gra...
DrawingMode
Specifies the drawing mode, also called primitive topology.
Encapsulates the current rendering state during a call to QSGMaterialShader::updateUniformData() and ...
The QSGMaterialShader class represents a graphics API independent shader program.
The QSGMaterial class encapsulates rendering state for a shader program.
\group qtquick-scenegraph-nodes \title Qt Quick Scene Graph Node classes
NodeType
Can be used to figure out the type of node.
NodeType type() const
Returns the type of this node.
The QSGRenderNode class represents a set of custom rendering commands targeting the graphics API that...
RenderMode
\value RenderMode2D Normal 2D rendering \value RenderMode2DNoDepthBuffer Normal 2D rendering with dep...
The renderer class is the abstract baseclass used for rendering the QML scene graph.
QMap< QString, QString > map
[6]
qDeleteAll(list.begin(), list.end())
size_t qHash(const GraphicsState &s, size_t seed) noexcept
QDebug operator<<(QDebug d, const Pt &p)
bool hasMaterialWithBlending(QSGGeometryNode *n)
bool operator==(const GraphicsState &a, const GraphicsState &b) noexcept
bool operator!=(const GraphicsState &a, const GraphicsState &b) noexcept
Combined button and popup list for selecting options.
#define Q_DECLARE_FLAGS(Flags, Enum)
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLint GLint GLint GLint GLint x
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLenum GLenum dstAlpha
GLdouble GLdouble GLdouble GLdouble top
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLenum GLenum srcAlpha
GLsizei GLenum const void * indices
GLfixed GLfixed GLint GLint order
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
#define QSG_RENDERER_COORD_LIMIT
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
unsigned long long quint64
QSvgRenderer * renderer
[0]
StencilClipState stencilClipState
QDataBuffer< DrawSet > drawSets
uint nonDynamicChangeCount
const QSGClipNode * clipList
DrawSet(int v, int z, int i)
QRhiGraphicsPipeline * depthPostPassPs
QRhiShaderResourceBindings * srb
QRhiGraphicsPipeline * ps
void setNode(QSGGeometryNode *n)
uint boundsOutsideFloatRange
const ShaderManagerShader * sms
size_t srbLayoutDescriptionHash
size_t renderTargetDescriptionHash
static GraphicsPipelineStateKey create(const GraphicsState &state, const ShaderManagerShader *sms, const QRhiRenderPassDescriptor *rpDesc, const QRhiShaderResourceBindings *srb)
QVector< quint32 > renderTargetDescription
QVector< quint32 > srbLayoutDescription
QSGNode::NodeType type() const
BatchRootInfo * rootInfo() const
QSGNode::DirtyState dirtyState
ClipBatchRootInfo * clipInfo() const
Node * firstChild() const
RenderNodeElement * renderNodeElement() const
Element * element() const
bool hasChild(Node *child) const
void map(const QMatrix4x4 &mat)
void set(float nx, float ny)
void operator|=(const Pt &pt)
void set(float left, float top, float right, float bottom)
bool isOutsideFloatRange() const
bool intersects(const Rect &r)
RenderNodeElement(QSGRenderNode *rn)
QSGRenderNode * renderNode
QRhiDepthStencilClearValue dsClear
ShaderManager::Shader * sms
quint64 timePrepareOpaque
QVarLengthArray< PreparedRenderBatch, 64 > opaqueRenderBatches
QVarLengthArray< PreparedRenderBatch, 64 > alphaRenderBatches
QSGRendererInterface::RenderMode renderMode
QRhiVertexInputLayout inputLayout
QVarLengthArray< QRhiShaderStage, 2 > stages
QRhiCommandBuffer::IndexFormat indexFormat
QDataBuffer< StencilDrawCall > drawCalls
The QSGMaterialType class is used as a unique type token in combination with QSGMaterial.