Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qsgbatchrenderer_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2016 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
3// Copyright (C) 2016 Robin Burchell <robin.burchell@viroteck.net>
4// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
5
6#ifndef QSGBATCHRENDERER_P_H
7#define QSGBATCHRENDERER_P_H
8
9//
10// W A R N I N G
11// -------------
12//
13// This file is not part of the Qt API. It exists purely as an
14// implementation detail. This header file may change from version to
15// version without notice, or even be removed.
16//
17// We mean it.
18//
19
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>
26
27#include <QtCore/QBitArray>
28#include <QtCore/QStack>
29
30#include <rhi/qrhi.h>
31
33
34namespace QSGBatchRenderer
35{
36
37#define QSG_RENDERER_COORD_LIMIT 1000000.0f
38
39struct Vec;
40struct Rect;
41struct Buffer;
42struct Chunk;
43struct Batch;
44struct Node;
45class Updater;
46class Renderer;
47class ShaderManager;
48
49template <typename Type, int PageSize> class AllocatorPage
50{
51public:
52 // The memory used by this allocator
53 char data[sizeof(Type) * PageSize];
54
55 // 'blocks' contains a list of free indices which can be allocated.
56 // The first available index is found in PageSize - available.
57 int blocks[PageSize];
58
59 // 'available' is the number of available instances this page has left to allocate.
61
62 // This is not strictly needed, but useful for sanity checking and anyway
63 // pretty small..
65
67 : available(PageSize)
68 , allocated(PageSize)
69 {
70 for (int i=0; i<PageSize; ++i)
71 blocks[i] = i;
72
73 // Zero out all new pages.
74 memset(data, 0, sizeof(data));
75 }
76
77 const Type *at(uint index) const
78 {
79 return (Type *) &data[index * sizeof(Type)];
80 }
81
83 {
84 return (Type *) &data[index * sizeof(Type)];
85 }
86};
87
88template <typename Type, int PageSize> class Allocator
89{
90public:
92 {
93 pages.push_back(new AllocatorPage<Type, PageSize>());
94 }
95
97 {
99 }
100
102 {
104 for (int i = m_freePage; i < pages.size(); i++) {
105 if (pages.at(i)->available > 0) {
106 p = pages.at(i);
107 m_freePage = i;
108 break;
109 }
110 }
111
112 // we couldn't find a free page from m_freePage to the last page.
113 // either there is no free pages, or there weren't any in the area we
114 // scanned: rescanning is expensive, so let's just assume there isn't
115 // one. when an item is released, we'll reset m_freePage anyway.
116 if (!p) {
118 m_freePage = pages.size();
119 pages.push_back(p);
120 }
121 uint pos = p->blocks[PageSize - p->available];
122 void *mem = p->at(pos);
123 p->available--;
124 p->allocated.setBit(pos);
125 Type *t = (Type*)mem;
126 return t;
127 }
128
130 {
132 if (!page->allocated.testBit(index))
133 qFatal("Double delete in allocator: page=%d, index=%d", pageIndex , index);
134
135 // Zero this instance as we're done with it.
136 void *mem = page->at(index);
137 memset(mem, 0, sizeof(Type));
138
139 page->allocated[index] = false;
140 page->available++;
141 page->blocks[PageSize - page->available] = index;
142
143 // Remove the pages if they are empty and they are the last ones. We need to keep the
144 // order of pages since we have references to their index, so we can only remove
145 // from the end.
146 while (page->available == PageSize && pages.size() > 1 && pages.back() == page) {
147 pages.pop_back();
148 delete page;
149 page = pages.back();
150 }
151
152 // Reset the free page to force a scan for a new free point.
153 m_freePage = 0;
154 }
155
157 {
158 int pageIndex = -1;
159 for (int i=0; i<pages.size(); ++i) {
161 if ((Type *) (&p->data[0]) <= t && (Type *) (&p->data[PageSize * sizeof(Type)]) > t) {
162 pageIndex = i;
163 break;
164 }
165 }
166 Q_ASSERT(pageIndex >= 0);
167
169 int index = (quint64(t) - quint64(&page->data[0])) / sizeof(Type);
170
171 releaseExplicit(pageIndex, index);
172 }
173
175 int m_freePage = 0;
176};
177
178
180{
181 return (n->opaqueMaterial() ? n->opaqueMaterial()->flags() & QSGMaterial::Blending
182 : n->material()->flags() & QSGMaterial::Blending);
183}
184
185struct Pt {
186 float x, y;
187
188 void map(const QMatrix4x4 &mat) {
189 Pt r;
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];
193 x = r.x;
194 y = r.y;
195 }
196
197 void set(float nx, float ny) {
198 x = nx;
199 y = ny;
200 }
201};
202
203inline QDebug operator << (QDebug d, const Pt &p) {
204 d << "Pt(" << p.x << p.y << ")";
205 return d;
206}
207
208
209
210struct Rect {
211 Pt tl, br; // Top-Left (min) and Bottom-Right (max)
212
213 void operator |= (const Pt &pt) {
214 if (pt.x < tl.x)
215 tl.x = pt.x;
216 if (pt.x > br.x)
217 br.x = pt.x;
218 if (pt.y < tl.y)
219 tl.y = pt.y;
220 if (pt.y > br.y)
221 br.y = pt.y;
222 }
223
224 void operator |= (const Rect &r) {
225 if (r.tl.x < tl.x)
226 tl.x = r.tl.x;
227 if (r.tl.y < tl.y)
228 tl.y = r.tl.y;
229 if (r.br.x > br.x)
230 br.x = r.br.x;
231 if (r.br.y > br.y)
232 br.y = r.br.y;
233 }
234
235 void map(const QMatrix4x4 &m);
236
237 void set(float left, float top, float right, float bottom) {
238 tl.set(left, top);
239 br.set(right, bottom);
240 }
241
242 bool intersects(const Rect &r) {
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;
246 }
247
248 bool isOutsideFloatRange() const {
253 }
254};
255
256inline QDebug operator << (QDebug d, const Rect &r) {
257 d << "Rect(" << r.tl.x << r.tl.y << r.br.x << r.br.y << ")";
258 return d;
259}
260
261struct Buffer {
263 // Data is only valid while preparing the upload. Exception is if we are using the
264 // broken IBO workaround or we are using a visualization mode.
265 char *data;
268};
269
270struct Element {
275 , removed(false)
276 , orphaned(false)
279 {
280 }
281
283 node = n;
285 }
286
287 inline void ensureBoundsValid() {
288 if (!boundsComputed)
290 }
291 void computeBounds();
292
294 Batch *batch = nullptr;
296 Node *root = nullptr;
297
298 Rect bounds; // in device coordinates
299
300 int order = 0;
304
312};
313
314struct RenderNodeElement : public Element {
315
317 : renderNode(rn)
318 {
319 isRenderNode = true;
320 }
321
323};
324
328 Node *parentRoot = nullptr;
329 int lastOrder = -1;
330 int firstOrder = -1;
332};
333
335{
337};
338
340{
341 DrawSet(int v, int z, int i)
342 : vertices(v)
343 , zorders(z)
344 , indices(i)
345 {
346 }
348 int vertices = 0;
349 int zorders = 0;
350 int indices = 0;
351 int indexCount = 0;
352};
353
355{
359
361{
363 {
364 NoClip = 0x00,
366 StencilClip = 0x02
367 };
369
374
375 inline void reset();
376};
377
379{
380 StencilClipState() : drawCalls(1) { }
381
382 bool updateStencilBuffer = false;
384 QRhiBuffer *vbuf = nullptr;
385 QRhiBuffer *ibuf = nullptr;
386 QRhiBuffer *ubuf = nullptr;
387
396 };
398
399 inline void reset();
400};
401
402struct Batch
403{
404 Batch() : drawSets(1) {}
405 bool geometryWasChanged(QSGGeometryNode *gn);
406 BatchCompatibility isMaterialCompatible(Element *e) const;
407 void invalidate();
408 void cleanupRemovedElements();
409
410 bool isTranslateOnlyToRoot() const;
411 bool isSafeToBatch() const;
412
413 // pseudo-constructor...
414 void init() {
415 // Only non-reusable members are reset here. See Renderer::newBatch().
416 first = nullptr;
417 root = nullptr;
418 vertexCount = 0;
419 indexCount = 0;
420 isOpaque = false;
421 needsUpload = false;
422 merged = false;
423 positionAttribute = -1;
424 uploadedThisFrame = false;
425 isRenderNode = false;
426 ubufDataValid = false;
427 needsPurge = false;
428 clipState.reset();
429 blendConstant = QColor();
430 }
431
434
436
439
441
448
449 mutable uint uploadedThisFrame : 1; // solely for debugging purposes
450
457
459};
460
461// NOTE: Node is zero-initialized by the Allocator.
462struct Node
463{
465 void *data;
466
471
472 Node *parent() const { return m_parent; }
473
476 Q_ASSERT(!hasChild(child));
477 Q_ASSERT(child->m_parent == nullptr);
478 Q_ASSERT(child->m_next == nullptr);
479 Q_ASSERT(child->m_prev == nullptr);
480
481 if (!m_child) {
482 child->m_next = child;
483 child->m_prev = child;
484 m_child = child;
485 } else {
486 m_child->m_prev->m_next = child;
487 child->m_prev = m_child->m_prev;
488 m_child->m_prev = child;
489 child->m_next = m_child;
490 }
491 child->setParent(this);
492 }
493
496 Q_ASSERT(hasChild(child));
497
498 // only child..
499 if (child->m_next == child) {
500 m_child = nullptr;
501 } else {
502 if (m_child == child)
503 m_child = child->m_next;
504 child->m_next->m_prev = child->m_prev;
505 child->m_prev->m_next = child->m_next;
506 }
507 child->m_next = nullptr;
508 child->m_prev = nullptr;
509 child->setParent(nullptr);
510 }
511
512 Node *firstChild() const { return m_child; }
513
514 Node *sibling() const {
515 Q_ASSERT(m_parent);
516 return m_next == m_parent->m_child ? nullptr : m_next;
517 }
518
519 void setParent(Node *p) {
520 Q_ASSERT(m_parent == nullptr || p == nullptr);
521 m_parent = p;
522 }
523
524 bool hasChild(Node *child) const {
525 Node *n = m_child;
526 while (n && n != child)
527 n = n->sibling();
528 return n;
529 }
530
531
532
533 QSGNode::DirtyState dirtyState;
534
538
539 inline QSGNode::NodeType type() const { return sgNode->type(); }
540
541 inline Element *element() const {
543 return (Element *) data;
544 }
545
548 return (RenderNodeElement *) data;
549 }
550
551 inline ClipBatchRootInfo *clipInfo() const {
552 Q_ASSERT(sgNode->type() == QSGNode::ClipNodeType);
553 return (ClipBatchRootInfo *) data;
554 }
555
556 inline BatchRootInfo *rootInfo() const {
558 || (sgNode->type() == QSGNode::TransformNodeType && isBatchRoot));
559 return (BatchRootInfo *) data;
560 }
561};
562
564{
565public:
567
568 void visitOpacityNode(Node *n);
569 void visitTransformNode(Node *n);
570 void visitGeometryNode(Node *n);
571 void visitClipNode(Node *n);
573 void updateRootTransforms(Node *n, Node *root, const QMatrix4x4 &combined);
574
575 void updateStates(QSGNode *n) override;
576 void visitNode(Node *n);
577 void registerWithParentRoot(QSGNode *subRoot, QSGNode *parentRoot);
578
579private:
581
582 QDataBuffer<Node *> m_roots;
583 QDataBuffer<QMatrix4x4> m_rootMatrices;
584
585 int m_added;
586 int m_transformChange;
587 int m_opacityChange;
588
589 QMatrix4x4 m_identityMatrix;
590};
591
593{
594 bool depthTest = false;
595 bool depthWrite = false;
597 bool blending = false;
602 QRhiGraphicsPipeline::ColorMask colorWrite = QRhiGraphicsPipeline::ColorMask(0xF);
604 bool usesScissor = false;
605 bool stencilTest = false;
606 int sampleCount = 1;
608 float lineWidth = 1.0f;
610};
611
612bool operator==(const GraphicsState &a, const GraphicsState &b) noexcept;
613bool operator!=(const GraphicsState &a, const GraphicsState &b) noexcept;
614size_t qHash(const GraphicsState &s, size_t seed = 0) noexcept;
615
617
619{
624 struct {
627 } extra;
629 const ShaderManagerShader *sms,
630 const QRhiRenderPassDescriptor *rpDesc,
632 {
633 const QVector<quint32> rtDesc = rpDesc->serializedFormat();
634 const QVector<quint32> srbDesc = srb->serializedLayoutDescription();
635 return { state, sms, rtDesc, srbDesc, { qHash(rtDesc), qHash(srbDesc) } };
636 }
637};
638
639bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) noexcept;
640bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) noexcept;
641size_t qHash(const GraphicsPipelineStateKey &k, size_t seed = 0) noexcept;
642
644{
646 delete materialShader;
647 }
648 QSGMaterialShader *materialShader = nullptr;
652};
653
654class ShaderManager : public QObject
655{
657public:
659
662 qDeleteAll(rewrittenShaders);
663 qDeleteAll(stockShaders);
664 }
665
666 void clearCachedRendererData();
667
669
672
673public Q_SLOTS:
674 void invalidated();
675
676public:
677 Shader *prepareMaterial(QSGMaterial *material, const QSGGeometry *geometry = nullptr, QSGRendererInterface::RenderMode renderMode = QSGRendererInterface::RenderMode2D);
678 Shader *prepareMaterialNoRewrite(QSGMaterial *material, const QSGGeometry *geometry = nullptr, QSGRendererInterface::RenderMode renderMode = QSGRendererInterface::RenderMode2D);
679
680private:
682 QHash<ShaderKey, Shader *> rewrittenShaders;
683 QHash<ShaderKey, Shader *> stockShaders;
684
686};
687
689{
695};
696
698{
699public:
705 VisualizeOverdraw
706 };
707
709 virtual ~Visualizer();
710
711 VisualizeMode mode() const { return m_visualizeMode; }
712 void setMode(VisualizeMode mode) { m_visualizeMode = mode; }
713
714 virtual void visualizeChangesPrepare(Node *n, uint parentChanges = 0);
715 virtual void prepareVisualize() = 0;
716 virtual void visualize() = 0;
717
718 virtual void releaseResources() = 0;
719
720protected:
724};
725
726class Q_QUICK_PRIVATE_EXPORT Renderer : public QSGRenderer
727{
728public:
730 ~Renderer();
731
732protected:
733 void nodeChanged(QSGNode *node, QSGNode::DirtyState state) override;
734 void render() override;
735 void prepareInline() override;
736 void renderInline() override;
737 void releaseCachedResources() override;
738
740 const Batch *batch;
742 };
743
745 bool valid = false;
755 };
756
757 // update batches and queue and commit rhi resource updates
758 void prepareRenderPass(RenderPassContext *ctx);
759 // records the beginPass()
760 void beginRenderPass(RenderPassContext *ctx);
761 // records the draw calls, must be preceded by a prepareRenderPass at minimum,
762 // and also surrounded by begin/endRenderPass unless we are recording inside an
763 // already started pass.
764 void recordRenderPass(RenderPassContext *ctx);
765 // does visualizing if enabled and records the endPass()
766 void endRenderPass(RenderPassContext *ctx);
767
768private:
769 enum RebuildFlag {
770 BuildRenderListsForTaggedRoots = 0x0001,
771 BuildRenderLists = 0x0002,
772 BuildBatches = 0x0004,
773 FullRebuild = 0xffff
774 };
775
776 friend class Updater;
777 friend class RhiVisualizer;
778
779 void destroyGraphicsResources();
780 void map(Buffer *buffer, quint32 byteSize, bool isIndexBuf = false);
781 void unmap(Buffer *buffer, bool isIndexBuf = false);
782
783 void buildRenderListsFromScratch();
784 void buildRenderListsForTaggedRoots();
785 void tagSubRoots(Node *node);
786 void buildRenderLists(QSGNode *node);
787
788 void deleteRemovedElements();
789 void cleanupBatches(QDataBuffer<Batch *> *batches);
790 void prepareOpaqueBatches();
791 bool checkOverlap(int first, int last, const Rect &bounds);
792 void prepareAlphaBatches();
793 void invalidateBatchAndOverlappingRenderOrders(Batch *batch);
794
795 void uploadBatch(Batch *b);
796 void uploadMergedElement(Element *e, int vaOffset, char **vertexData, char **zData, char **indexData, void *iBasePtr, int *indexCount);
797
798 bool ensurePipelineState(Element *e, const ShaderManager::Shader *sms, bool depthPostPass = false);
799 QRhiTexture *dummyTexture();
800 void updateMaterialDynamicData(ShaderManager::Shader *sms, QSGMaterialShader::RenderState &renderState,
801 QSGMaterial *material, const Batch *batch, Element *e, int ubufOffset, int ubufRegionSize);
802 void updateMaterialStaticData(ShaderManager::Shader *sms, QSGMaterialShader::RenderState &renderState,
803 QSGMaterial *material, Batch *batch, bool *gstateChanged);
804 void checkLineWidth(QSGGeometry *g);
805 bool prepareRenderMergedBatch(Batch *batch, PreparedRenderBatch *renderBatch);
806 void renderMergedBatch(PreparedRenderBatch *renderBatch, bool depthPostPass = false);
807 bool prepareRenderUnmergedBatch(Batch *batch, PreparedRenderBatch *renderBatch);
808 void renderUnmergedBatch(PreparedRenderBatch *renderBatch, bool depthPostPass = false);
809 void setGraphicsPipeline(QRhiCommandBuffer *cb, const Batch *batch, Element *e, bool depthPostPass = false);
810 ClipState::ClipType updateStencilClip(const QSGClipNode *clip);
811 void updateClip(const QSGClipNode *clipList, const Batch *batch);
812 void applyClipStateToGraphicsState();
813 QRhiGraphicsPipeline *buildStencilPipeline(const Batch *batch, bool firstStencilClipInBatch);
814 void updateClipState(const QSGClipNode *clipList, Batch *batch);
815 void enqueueStencilDraw(const Batch *batch);
816 const QMatrix4x4 &matrixForRoot(Node *node);
817 void renderRenderNode(Batch *batch);
818 bool prepareRhiRenderNode(Batch *batch, PreparedRenderBatch *renderBatch);
819 void renderRhiRenderNode(const Batch *batch);
820 void setActiveShader(QSGMaterialShader *program, ShaderManager::Shader *shader);
821 void setActiveRhiShader(QSGMaterialShader *program, ShaderManager::Shader *shader);
822
823 bool changeBatchRoot(Node *node, Node *newRoot);
824 void registerBatchRoot(Node *childRoot, Node *parentRoot);
825 void removeBatchRootFromParent(Node *childRoot);
826 void nodeChangedBatchRoot(Node *node, Node *root);
827 void turnNodeIntoBatchRoot(Node *node);
828 void nodeWasTransformed(Node *node, int *vertexCount);
829 void nodeWasRemoved(Node *node);
830 void nodeWasAdded(QSGNode *node, Node *shadowParent);
831 BatchRootInfo *batchRootInfo(Node *node);
832 void updateLineWidth(QSGGeometry *g);
833
834 inline Batch *newBatch();
835 void invalidateAndRecycleBatch(Batch *b);
836 void releaseElement(Element *e, bool inDestructor = false);
837
838 void setVisualizationMode(const QByteArray &mode) override;
839 bool hasVisualizationModeWithContinuousUpdate() const override;
840
841 QSGDefaultRenderContext *m_context;
843 QSet<Node *> m_taggedRoots;
844 QDataBuffer<Element *> m_opaqueRenderList;
845 QDataBuffer<Element *> m_alphaRenderList;
846 int m_nextRenderOrder;
847 bool m_partialRebuild;
848 QSGNode *m_partialRebuildRoot;
849 bool m_forceNoDepthBuffer;
850
852 QDataBuffer<Batch *> m_opaqueBatches;
853 QDataBuffer<Batch *> m_alphaBatches;
855
856 QDataBuffer<Batch *> m_batchPool;
857 QDataBuffer<Element *> m_elementsToDelete;
858 QDataBuffer<Element *> m_tmpAlphaElements;
859 QDataBuffer<Element *> m_tmpOpaqueElements;
860
861 uint m_rebuild;
862 qreal m_zRange;
863#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
864 int m_renderOrderRebuildLower;
865 int m_renderOrderRebuildUpper;
866#endif
867
868 int m_batchNodeThreshold;
869 int m_batchVertexThreshold;
870 int m_srbPoolThreshold;
871
872 Visualizer *m_visualizer;
873
874 ShaderManager *m_shaderManager; // per rendercontext, shared
875 QSGMaterial *m_currentMaterial;
876 QSGMaterialShader *m_currentProgram;
877 ShaderManager::Shader *m_currentShader;
878 ClipState m_currentClipState;
879
880 QDataBuffer<char> m_vertexUploadPool;
881 QDataBuffer<char> m_indexUploadPool;
882
883 Allocator<Node, 256> m_nodeAllocator;
884 Allocator<Element, 64> m_elementAllocator;
885
886 RenderPassContext m_mainRenderPassContext;
887 QRhiResourceUpdateBatch *m_resourceUpdates = nullptr;
888 uint m_ubufAlignment;
889 bool m_uint32IndexForRhi;
890 GraphicsState m_gstate;
891 RenderPassState m_pstate;
892 QStack<GraphicsState> m_gstateStack;
894 QRhiTexture *m_dummyTexture = nullptr;
895
896 struct StencilClipCommonData {
897 QRhiGraphicsPipeline *replacePs = nullptr;
898 QRhiGraphicsPipeline *incrPs = nullptr;
899 QShader vs;
900 QShader fs;
901 QRhiVertexInputLayout inputLayout;
903 inline void reset();
904 } m_stencilClipCommon;
905
906 inline int mergedIndexElemSize() const;
907 inline bool useDepthBuffer() const;
908 inline void setStateForDepthPostPass();
909};
910
911Batch *Renderer::newBatch()
912{
913 Batch *b;
914 int size = m_batchPool.size();
915 if (size) {
916 b = m_batchPool.at(size - 1);
917 // vbo, ibo, ubuf, stencil-related buffers are reused
918 m_batchPool.resize(size - 1);
919 } else {
920 b = new Batch();
921 Q_ASSERT(offsetof(Batch, ibo) == sizeof(Buffer) + offsetof(Batch, vbo));
922 memset(&b->vbo, 0, sizeof(Buffer) * 2); // Clear VBO & IBO
923 b->ubuf = nullptr;
924 b->stencilClipState.reset();
925 }
926 // initialize (when new batch) or reset (when reusing a batch) the non-reusable fields
927 b->init();
928 return b;
929}
930
931int Renderer::mergedIndexElemSize() const
932{
933 return m_uint32IndexForRhi ? sizeof(quint32) : sizeof(quint16);
934}
935
936// "use" here means that both depth test and write is wanted (the latter for
937// opaque batches only). Therefore neither RenderMode2DNoDepthBuffer nor
938// RenderMode3D must result in true. So while RenderMode3D requires a depth
939// buffer, this here must say false. In addition, m_forceNoDepthBuffer is a
940// dynamic override relevant with QSGRenderNode.
941//
942bool Renderer::useDepthBuffer() const
943{
944 return !m_forceNoDepthBuffer && m_renderMode == QSGRendererInterface::RenderMode2D;
945}
946
947void Renderer::setStateForDepthPostPass()
948{
949 m_gstate.colorWrite = {};
950 m_gstate.depthWrite = true;
951 m_gstate.depthTest = true;
952 m_gstate.depthFunc = QRhiGraphicsPipeline::Less;
953}
954
955void Renderer::StencilClipCommonData::reset()
956{
957 delete replacePs;
958 replacePs = nullptr;
959
960 delete incrPs;
961 incrPs = nullptr;
962
963 vs = QShader();
964 fs = QShader();
965}
966
968{
969 clipList = nullptr;
970 type = NoClip;
971 stencilRef = 0;
972}
973
975{
976 updateStencilBuffer = false;
977
978 delete srb;
979 srb = nullptr;
980
981 delete vbuf;
982 vbuf = nullptr;
983
984 delete ibuf;
985 ibuf = nullptr;
986
987 delete ubuf;
988 ubuf = nullptr;
989
990 drawCalls.reset();
991}
992
993}
994
999
1001
1002#endif // QSGBATCHRENDERER_P_H
Definition lalr.h:137
\inmodule QtCore
Definition qbitarray.h:13
\inmodule QtCore
Definition qbytearray.h:57
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
Definition qbytearray.h:534
char at(qsizetype i) const
Returns the byte at index position i in the byte array.
Definition qbytearray.h:523
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
\inmodule QtCore
\inmodule QtCore
\inmodule QtCore
Definition qhash.h:818
Definition qlist.h:74
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:25
const float * constData() const
Returns a constant pointer to the raw data of this matrix.
Definition qmatrix4x4.h:147
\inmodule QtCore
Definition qhash.h:1348
\inmodule QtCore
Definition qobject.h:90
\inmodule QtGui
Definition qrhi.h:834
\inmodule QtGui
Definition qrhi.h:1614
IndexFormat
Specifies the index data type.
Definition qrhi.h:1616
\inmodule QtGui
Definition qrhi.h:44
\inmodule QtGui
Definition qrhi.h:1241
PolygonMode
Specifies the polygon rasterization mode.
Definition qrhi.h:1350
BlendFactor
Specifies the blend factor.
Definition qrhi.h:1280
CompareOp
Specifies the depth or stencil comparison function.
Definition qrhi.h:1321
CullMode
Specifies the culling mode.
Definition qrhi.h:1261
Topology
Specifies the primitive topology.
Definition qrhi.h:1251
\inmodule QtGui
Definition qrhi.h:1119
virtual QVector< quint32 > serializedFormat() const =0
\inmodule QtGui
Definition qrhi.h:1694
\inmodule QtGui
Definition qrhi.h:138
\inmodule QtGui
Definition qrhi.h:1190
QVector< quint32 > serializedLayoutDescription() const
Definition qrhi.h:1208
\inmodule QtGui
Definition qrhi.h:883
\inmodule QtGui
Definition qrhi.h:313
\inmodule QtGui
Definition qrhi.h:85
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
virtual void releaseResources()=0
QHash< Node *, uint > m_visualizeChangeSet
The QSGClipNode class implements the clipping functionality in the scene graph.
Definition qsgnode.h:224
The QSGGeometryNode class is used for all rendered content in the scene graph.
Definition qsgnode.h:191
The QSGGeometry class provides low-level storage for graphics primitives in the \l{Qt Quick Scene Gra...
Definition qsggeometry.h:15
DrawingMode
Specifies the drawing mode, also called primitive topology.
Definition qsggeometry.h:33
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.
Definition qsgmaterial.h:15
\group qtquick-scenegraph-nodes \title Qt Quick Scene Graph Node classes
Definition qsgnode.h:37
NodeType
Can be used to figure out the type of node.
Definition qsgnode.h:39
@ TransformNodeType
Definition qsgnode.h:42
@ GeometryNodeType
Definition qsgnode.h:41
@ RenderNodeType
Definition qsgnode.h:46
@ ClipNodeType
Definition qsgnode.h:43
NodeType type() const
Returns the type of this node.
Definition qsgnode.h:110
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.
Definition qset.h:18
\inmodule QtGui
Definition qshader.h:81
\inmodule QtCore
Definition qstack.h:13
EGLContext ctx
QMap< QString, QString > map
[6]
qDeleteAll(list.begin(), list.end())
double e
else opt state
[0]
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.
static void * context
std::pair< T1, T2 > QPair
#define Q_DECLARE_FLAGS(Flags, Enum)
Definition qflags.h:174
#define qFatal
Definition qlogging.h:164
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLint GLint GLint GLint GLint x
[0]
GLenum mode
const GLfloat * m
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLboolean r
[2]
GLenum GLenum GLenum GLenum dstAlpha
GLdouble GLdouble GLdouble GLdouble top
GLdouble GLdouble right
GLenum GLenum GLenum srcAlpha
GLenum GLuint buffer
GLint left
GLenum type
GLint GLint bottom
GLuint program
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLboolean GLboolean g
GLint first
GLfloat n
GLsizei GLenum const void * indices
GLint y
GLboolean reset
GLbyte nx
GLfixed ny
GLuint shader
Definition qopenglext.h:665
GLdouble GLdouble t
Definition qopenglext.h:243
GLdouble s
[6]
Definition qopenglext.h:235
GLfloat GLfloat p
[1]
GLfixed GLfixed GLint GLint order
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
Definition qrandom.cpp:196
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#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_OBJECT
#define Q_SLOTS
@ Q_PRIMITIVE_TYPE
Definition qtypeinfo.h:144
@ Q_RELOCATABLE_TYPE
Definition qtypeinfo.h:145
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:163
unsigned int quint32
Definition qtypes.h:45
unsigned short quint16
Definition qtypes.h:43
unsigned long long quint64
Definition qtypes.h:56
unsigned int uint
Definition qtypes.h:29
double qreal
Definition qtypes.h:92
QObject::connect nullptr
QByteArray page
[45]
QLayoutItem * child
[0]
myWidget render(this)
QSvgRenderer * renderer
[0]
StencilClipState stencilClipState
QDataBuffer< DrawSet > drawSets
DrawSet(int v, int z, int i)
QRhiGraphicsPipeline * depthPostPassPs
QRhiShaderResourceBindings * srb
QRhiGraphicsPipeline * ps
void setNode(QSGGeometryNode *n)
static GraphicsPipelineStateKey create(const GraphicsState &state, const ShaderManagerShader *sms, const QRhiRenderPassDescriptor *rpDesc, const QRhiShaderResourceBindings *srb)
QSGNode::NodeType type() const
BatchRootInfo * rootInfo() const
QSGNode::DirtyState dirtyState
ClipBatchRootInfo * clipInfo() const
RenderNodeElement * renderNodeElement() 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 intersects(const Rect &r)
QRhiDepthStencilClearValue dsClear
QVarLengthArray< PreparedRenderBatch, 64 > opaqueRenderBatches
QVarLengthArray< PreparedRenderBatch, 64 > alphaRenderBatches
QVarLengthArray< QRhiShaderStage, 2 > stages
QDataBuffer< StencilDrawCall > drawCalls
Definition moc.h:24