Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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 {
103 AllocatorPage<Type, PageSize> *p = 0;
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) {
117 p = new AllocatorPage<Type, PageSize>();
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 {
131 AllocatorPage<Type, PageSize> *page = pages.at(pageIndex);
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) {
160 AllocatorPage<Type, PageSize> *p = pages.at(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
168 AllocatorPage<Type, PageSize> *page = pages.at(pageIndex);
169 int index = (quint64(t) - quint64(&page->data[0])) / sizeof(Type);
170
171 releaseExplicit(pageIndex, index);
172 }
173
174 QVector<AllocatorPage<Type, PageSize> *> pages;
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
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
313
314struct RenderNodeElement : public Element {
315
317 : renderNode(rn)
318 {
319 isRenderNode = true;
320 }
321
323};
324
327 QSet<Node *> subRoots;
328 Node *parentRoot = nullptr;
329 int lastOrder = -1;
330 int firstOrder = -1;
332};
333
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
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
397 QDataBuffer<StencilDrawCall> drawCalls;
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
458 QDataBuffer<DrawSet> drawSets;
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
614
615bool operator==(const GraphicsState &a, const GraphicsState &b) noexcept;
616bool operator!=(const GraphicsState &a, const GraphicsState &b) noexcept;
617size_t qHash(const GraphicsState &s, size_t seed = 0) noexcept;
618
620
622{
625 QVector<quint32> renderTargetDescription;
626 QVector<quint32> srbLayoutDescription;
627 struct {
630 } extra;
632 const ShaderManagerShader *sms,
633 const QRhiRenderPassDescriptor *rpDesc,
635 {
636 const QVector<quint32> rtDesc = rpDesc->serializedFormat();
637 const QVector<quint32> srbDesc = srb->serializedLayoutDescription();
638 return { state, sms, rtDesc, srbDesc, { qHash(rtDesc), qHash(srbDesc) } };
639 }
640};
641
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;
645
652
653bool operator==(const ShaderKey &a, const ShaderKey &b) noexcept;
654bool operator!=(const ShaderKey &a, const ShaderKey &b) noexcept;
655size_t qHash(const ShaderKey &k, size_t seed = 0) noexcept;
656
658{
660 delete materialShader;
661 }
662 QSGMaterialShader *materialShader = nullptr;
664 QVarLengthArray<QRhiShaderStage, 2> stages;
666};
667
668class ShaderManager : public QObject
669{
671public:
673
676 qDeleteAll(rewrittenShaders);
677 qDeleteAll(stockShaders);
678 }
679
680 void clearCachedRendererData();
681
682 QHash<GraphicsPipelineStateKey, QRhiGraphicsPipeline *> pipelineCache;
683
684 QMultiHash<QVector<quint32>, QRhiShaderResourceBindings *> srbPool;
686
687public Q_SLOTS:
688 void invalidated();
689
690public:
691 Shader *prepareMaterial(QSGMaterial *material,
692 const QSGGeometry *geometry = nullptr,
694 int multiViewCount = 0);
695 Shader *prepareMaterialNoRewrite(QSGMaterial *material,
696 const QSGGeometry *geometry = nullptr,
698 int multiViewCount = 0);
699
700private:
701 QHash<ShaderKey, Shader *> rewrittenShaders;
702 QHash<ShaderKey, Shader *> stockShaders;
703
705};
706
715
717{
718public:
726
728 virtual ~Visualizer();
729
730 VisualizeMode mode() const { return m_visualizeMode; }
731 void setMode(VisualizeMode mode) { m_visualizeMode = mode; }
732
733 virtual void visualizeChangesPrepare(Node *n, uint parentChanges = 0);
734 virtual void prepareVisualize() = 0;
735 virtual void visualize() = 0;
736
737 virtual void releaseResources() = 0;
738
739protected:
742 QHash<Node *, uint> m_visualizeChangeSet;
743};
744
745class Q_QUICK_EXPORT Renderer : public QSGRenderer
746{
747public:
749 ~Renderer();
750
751protected:
752 void nodeChanged(QSGNode *node, QSGNode::DirtyState state) override;
753 void render() override;
754 void prepareInline() override;
755 void renderInline() override;
756 void releaseCachedResources() override;
757
762
775
776 // update batches and queue and commit rhi resource updates
777 void prepareRenderPass(RenderPassContext *ctx);
778 // records the beginPass()
779 void beginRenderPass(RenderPassContext *ctx);
780 // records the draw calls, must be preceded by a prepareRenderPass at minimum,
781 // and also surrounded by begin/endRenderPass unless we are recording inside an
782 // already started pass.
783 void recordRenderPass(RenderPassContext *ctx);
784 // does visualizing if enabled and records the endPass()
785 void endRenderPass(RenderPassContext *ctx);
786
787private:
788 enum RebuildFlag {
789 BuildRenderListsForTaggedRoots = 0x0001,
790 BuildRenderLists = 0x0002,
791 BuildBatches = 0x0004,
792 FullRebuild = 0xffff
793 };
794
795 friend class Updater;
796 friend class RhiVisualizer;
797
798 void destroyGraphicsResources();
799 void map(Buffer *buffer, quint32 byteSize, bool isIndexBuf = false);
800 void unmap(Buffer *buffer, bool isIndexBuf = false);
801
802 void buildRenderListsFromScratch();
803 void buildRenderListsForTaggedRoots();
804 void tagSubRoots(Node *node);
805 void buildRenderLists(QSGNode *node);
806
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);
813
814 void uploadBatch(Batch *b);
815 void uploadMergedElement(Element *e, int vaOffset, char **vertexData, char **zData, char **indexData, void *iBasePtr, int *indexCount);
816
817 bool ensurePipelineState(Element *e, const ShaderManager::Shader *sms, bool depthPostPass = false);
818 QRhiTexture *dummyTexture();
819 void updateMaterialDynamicData(ShaderManager::Shader *sms, QSGMaterialShader::RenderState &renderState,
820 QSGMaterial *material, const Batch *batch, Element *e, int ubufOffset, int ubufRegionSize);
821 void updateMaterialStaticData(ShaderManager::Shader *sms, QSGMaterialShader::RenderState &renderState,
822 QSGMaterial *material, Batch *batch, bool *gstateChanged);
823 void checkLineWidth(QSGGeometry *g);
824 bool prepareRenderMergedBatch(Batch *batch, PreparedRenderBatch *renderBatch);
825 void renderMergedBatch(PreparedRenderBatch *renderBatch, bool depthPostPass = false);
826 bool prepareRenderUnmergedBatch(Batch *batch, PreparedRenderBatch *renderBatch);
827 void renderUnmergedBatch(PreparedRenderBatch *renderBatch, bool depthPostPass = false);
828 void setGraphicsPipeline(QRhiCommandBuffer *cb, const Batch *batch, Element *e, bool depthPostPass = false);
829 ClipState::ClipType updateStencilClip(const QSGClipNode *clip);
830 void updateClip(const QSGClipNode *clipList, const Batch *batch);
831 void applyClipStateToGraphicsState();
832 QRhiGraphicsPipeline *buildStencilPipeline(const Batch *batch, bool firstStencilClipInBatch);
833 void updateClipState(const QSGClipNode *clipList, Batch *batch);
834 void enqueueStencilDraw(const Batch *batch);
835 const QMatrix4x4 &matrixForRoot(Node *node);
836 void renderRenderNode(Batch *batch);
837 bool prepareRhiRenderNode(Batch *batch, PreparedRenderBatch *renderBatch);
838 void renderRhiRenderNode(const Batch *batch);
839 void setActiveShader(QSGMaterialShader *program, ShaderManager::Shader *shader);
840 void setActiveRhiShader(QSGMaterialShader *program, ShaderManager::Shader *shader);
841
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);
850 BatchRootInfo *batchRootInfo(Node *node);
851 void updateLineWidth(QSGGeometry *g);
852
853 inline Batch *newBatch();
854 void invalidateAndRecycleBatch(Batch *b);
855 void releaseElement(Element *e, bool inDestructor = false);
856
857 void setVisualizationMode(const QByteArray &mode) override;
858 bool hasVisualizationModeWithContinuousUpdate() const override;
859
860 QSGDefaultRenderContext *m_context;
862 QSet<Node *> m_taggedRoots;
863 QDataBuffer<Element *> m_opaqueRenderList;
864 QDataBuffer<Element *> m_alphaRenderList;
865 int m_nextRenderOrder;
866 bool m_partialRebuild;
867 QSGNode *m_partialRebuildRoot;
868 bool m_forceNoDepthBuffer;
869
870 QHash<QSGRenderNode *, RenderNodeElement *> m_renderNodeElements;
871 QDataBuffer<Batch *> m_opaqueBatches;
872 QDataBuffer<Batch *> m_alphaBatches;
873 QHash<QSGNode *, Node *> m_nodes;
874
875 QDataBuffer<Batch *> m_batchPool;
876 QDataBuffer<Element *> m_elementsToDelete;
877 QDataBuffer<Element *> m_tmpAlphaElements;
878 QDataBuffer<Element *> m_tmpOpaqueElements;
879
880 QDataBuffer<QRhiBuffer *> m_vboPool;
881 QDataBuffer<QRhiBuffer *> m_iboPool;
882
883 uint m_rebuild;
884 qreal m_zRange;
885#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
886 int m_renderOrderRebuildLower;
887 int m_renderOrderRebuildUpper;
888#endif
889
890 int m_batchNodeThreshold;
891 int m_batchVertexThreshold;
892 int m_srbPoolThreshold;
893
894 Visualizer *m_visualizer;
895
896 ShaderManager *m_shaderManager; // per rendercontext, shared
897 QSGMaterial *m_currentMaterial;
898 QSGMaterialShader *m_currentProgram;
899 ShaderManager::Shader *m_currentShader;
900 ClipState m_currentClipState;
901
902 QDataBuffer<char> m_vertexUploadPool;
903 QDataBuffer<char> m_indexUploadPool;
904
905 Allocator<Node, 256> m_nodeAllocator;
906 Allocator<Element, 64> m_elementAllocator;
907
908 RenderPassContext m_mainRenderPassContext;
909 QRhiResourceUpdateBatch *m_resourceUpdates = nullptr;
910 uint m_ubufAlignment;
911 bool m_uint32IndexForRhi;
912 GraphicsState m_gstate;
913 RenderPassState m_pstate;
914 QStack<GraphicsState> m_gstateStack;
915 QHash<QSGSamplerDescription, QRhiSampler *> m_samplers;
916 QRhiTexture *m_dummyTexture = nullptr;
917
918 struct StencilClipCommonData {
919 QRhiGraphicsPipeline *replacePs = nullptr;
920 QRhiGraphicsPipeline *incrPs = nullptr;
921 QShader vs;
922 QShader fs;
923 QRhiVertexInputLayout inputLayout;
925 inline void reset();
926 } m_stencilClipCommon;
927
928 inline int mergedIndexElemSize() const;
929 inline bool useDepthBuffer() const;
930 inline void setStateForDepthPostPass();
931};
932
933Batch *Renderer::newBatch()
934{
935 Batch *b;
936 int size = m_batchPool.size();
937 if (size) {
938 b = m_batchPool.at(size - 1);
939 // vbo, ibo, ubuf, stencil-related buffers are reused
940 m_batchPool.resize(size - 1);
941 } else {
942 b = new Batch();
943 Q_ASSERT(offsetof(Batch, ibo) == sizeof(Buffer) + offsetof(Batch, vbo));
944 memset(&b->vbo, 0, sizeof(Buffer) * 2); // Clear VBO & IBO
945 b->ubuf = nullptr;
946 b->stencilClipState.reset();
947 }
948 // initialize (when new batch) or reset (when reusing a batch) the non-reusable fields
949 b->init();
950 return b;
951}
952
953int Renderer::mergedIndexElemSize() const
954{
955 return m_uint32IndexForRhi ? sizeof(quint32) : sizeof(quint16);
956}
957
958// "use" here means that both depth test and write is wanted (the latter for
959// opaque batches only). Therefore neither RenderMode2DNoDepthBuffer nor
960// RenderMode3D must result in true. So while RenderMode3D requires a depth
961// buffer, this here must say false. In addition, m_forceNoDepthBuffer is a
962// dynamic override relevant with QSGRenderNode.
963//
964bool Renderer::useDepthBuffer() const
965{
966 return !m_forceNoDepthBuffer && m_renderMode == QSGRendererInterface::RenderMode2D;
967}
968
969void Renderer::setStateForDepthPostPass()
970{
971 m_gstate.colorWrite = {};
972 m_gstate.depthWrite = true;
973 m_gstate.depthTest = true;
974 m_gstate.depthFunc = QRhiGraphicsPipeline::Less;
975}
976
977void Renderer::StencilClipCommonData::reset()
978{
979 delete replacePs;
980 replacePs = nullptr;
981
982 delete incrPs;
983 incrPs = nullptr;
984
985 vs = QShader();
986 fs = QShader();
987}
988
990{
991 clipList = nullptr;
992 type = NoClip;
993 stencilRef = 0;
994}
995
997{
998 updateStencilBuffer = false;
999
1000 delete srb;
1001 srb = nullptr;
1002
1003 delete vbuf;
1004 vbuf = nullptr;
1005
1006 delete ibuf;
1007 ibuf = nullptr;
1008
1009 delete ubuf;
1010 ubuf = nullptr;
1011
1012 drawCalls.reset();
1013}
1014
1015}
1016
1021
1023
1024#endif // QSGBATCHRENDERER_P_H
Definition lalr.h:136
\inmodule QtCore
Definition qbitarray.h:13
\inmodule QtCore
Definition qbytearray.h:57
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
Definition qbytearray.h:611
char at(qsizetype i) const
Returns the byte at index position i in the byte array.
Definition qbytearray.h:600
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
\inmodule QtCore
\inmodule QtCore
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:25
\inmodule QtCore
Definition qobject.h:103
\inmodule QtGui
Definition qrhi.h:846
\inmodule QtGui
Definition qrhi.h:1651
IndexFormat
Specifies the index data type.
Definition qrhi.h:1653
\inmodule QtGui
Definition qrhi.h:44
\inmodule QtGui
Definition qrhi.h:1270
BlendOp
Specifies the blend operation.
Definition qrhi.h:1331
PolygonMode
Specifies the polygon rasterization mode.
Definition qrhi.h:1379
BlendFactor
Specifies the blend factor.
Definition qrhi.h:1309
CompareOp
Specifies the depth or stencil comparison function.
Definition qrhi.h:1350
CullMode
Specifies the culling mode.
Definition qrhi.h:1290
Topology
Specifies the primitive topology.
Definition qrhi.h:1280
\inmodule QtGui
Definition qrhi.h:1142
virtual QVector< quint32 > serializedFormat() const =0
\inmodule QtGui
Definition qrhi.h:1731
\inmodule QtGui
Definition qrhi.h:138
\inmodule QtGui
Definition qrhi.h:1214
QVector< quint32 > serializedLayoutDescription() const
Definition qrhi.h:1232
\inmodule QtGui
Definition qrhi.h:895
\inmodule QtGui
Definition qrhi.h:321
\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:221
The QSGGeometryNode class is used for all rendered content in the scene graph.
Definition qsgnode.h:188
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.
\inmodule QtGui
Definition qshader.h:81
EGLContext ctx
QMap< QString, QString > map
[6]
qDeleteAll(list.begin(), list.end())
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
#define Q_DECLARE_FLAGS(Flags, Enum)
Definition qflags.h:174
#define qFatal
Definition qlogging.h:168
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
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLenum GLenum srcAlpha
GLenum GLuint buffer
GLint left
GLenum type
GLint GLint bottom
GLuint program
GLboolean GLboolean g
GLint first
GLfloat n
GLsizei GLenum const void * indices
GLint y
GLdouble s
[6]
Definition qopenglext.h:235
GLboolean reset
GLbyte nx
GLfixed ny
GLuint shader
Definition qopenglext.h:665
GLdouble GLdouble t
Definition qopenglext.h:243
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:157
@ Q_RELOCATABLE_TYPE
Definition qtypeinfo.h:158
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:180
unsigned int quint32
Definition qtypes.h:50
unsigned short quint16
Definition qtypes.h:48
unsigned long long quint64
Definition qtypes.h:61
unsigned int uint
Definition qtypes.h:34
double qreal
Definition qtypes.h:187
float vertexData[]
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
QSGRendererInterface::RenderMode renderMode
QVarLengthArray< QRhiShaderStage, 2 > stages
QDataBuffer< StencilDrawCall > drawCalls
The QSGMaterialType class is used as a unique type token in combination with QSGMaterial.
Definition moc.h:23