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/QElapsedTimer>
29#include <QtCore/QStack>
38#define QSG_RENDERER_COORD_LIMIT 1000000.0f
54 char data[
sizeof(Type) * PageSize];
71 for (
int i=0; i<PageSize; ++i)
78 const Type *
at(uint index)
const
80 return (Type *) &
data[index *
sizeof(Type)];
85 return (Type *) &
data[index *
sizeof(Type)];
89template <
typename Type,
int PageSize>
class Allocator
94 pages.push_back(
new AllocatorPage<Type, PageSize>());
105 for (
int i =
m_freePage; i < pages.size(); i++) {
106 if (pages.at(i)->available > 0) {
119 m_freePage = pages.size();
122 uint pos = p->blocks[PageSize - p->available];
123 void *mem = p->at(pos);
125 p->allocated.setBit(pos);
126 Type *t = (Type*)mem;
133 if (!page->allocated.testBit(index))
134 qFatal(
"Double delete in allocator: page=%d, index=%d", pageIndex , index);
137 void *mem = page->at(index);
138 memset(mem, 0,
sizeof(Type));
140 page->allocated[index] =
false;
142 page->blocks[PageSize - page->available] = index;
147 while (page->available == PageSize && pages.size() > 1 && pages.back() == page) {
160 for (
int i=0; i<pages.size(); ++i) {
162 if ((Type *) (&p->data[0]) <= t && (Type *) (&p->data[PageSize *
sizeof(Type)]) > t) {
167 Q_ASSERT(pageIndex >= 0);
170 int index = (quint64(t) - quint64(&page->data[0])) /
sizeof(Type);
172 releaseExplicit(pageIndex, index);
182 return (n->opaqueMaterial() ? n->opaqueMaterial()->flags() & QSGMaterial::Blending
183 : n->material()->flags() & QSGMaterial::Blending);
189 void map(
const QMatrix4x4 &mat) {
191 const float *m = mat.constData();
192 r
.x =
x * m[0] +
y * m[4] + m[12];
193 r
.y =
x * m[1] +
y * m[5] + m[13];
198 void set(
float nx,
float ny) {
205 d <<
"Pt(" << p
.x << p
.y <<
")";
236 void map(
const QMatrix4x4 &m);
238 void set(
float left,
float top,
float right,
float bottom) {
246 return xOverlap && yOverlap;
285 isMaterialBlended = hasMaterialWithBlending(n);
425 uploadedThisFrame =
false;
426 isRenderNode =
false;
427 ubufDataValid =
false;
430 blendConstant = QColor();
521 Q_ASSERT(
m_parent ==
nullptr || p ==
nullptr);
527 while (n && n != child)
543 Q_ASSERT(sgNode->type() == QSGNode::GeometryNodeType);
548 Q_ASSERT(sgNode->type() == QSGNode::RenderNodeType);
553 Q_ASSERT(sgNode->type() == QSGNode::ClipNodeType);
558 Q_ASSERT(sgNode->type() == QSGNode::ClipNodeType
559 || (sgNode->type() == QSGNode::TransformNodeType && isBatchRoot));
583 QDataBuffer<Node *> m_roots;
584 QDataBuffer<QMatrix4x4> m_rootMatrices;
587 int m_transformChange;
590 QMatrix4x4 m_identityMatrix;
634 const QRhiRenderPassDescriptor *rpDesc,
635 const QRhiShaderResourceBindings *srb)
637 const QVector<quint32> rtDesc = rpDesc->serializedFormat();
638 const QVector<quint32> srbDesc = srb->serializedLayoutDescription();
639 return { state, sms, rtDesc, srbDesc, { qHash(rtDesc), qHash(srbDesc) } };
661 delete materialShader;
677 qDeleteAll(rewrittenShaders);
678 qDeleteAll(stockShaders);
693 const QSGGeometry *geometry =
nullptr,
695 int multiViewCount = 0);
697 const QSGGeometry *geometry =
nullptr,
699 int multiViewCount = 0);
702 QHash<ShaderKey, Shader *> rewrittenShaders;
703 QHash<ShaderKey, Shader *> stockShaders;
705 QSGDefaultRenderContext *context;
890#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
const Type * at(uint index) const
char data[sizeof(Type) *PageSize]
QVector< AllocatorPage< Type, PageSize > * > pages
void releaseExplicit(uint pageIndex, uint index)
void clearCachedRendererData()
Shader * prepareMaterial(QSGMaterial *material, const QSGGeometry *geometry=nullptr, QSGRendererInterface::RenderMode renderMode=QSGRendererInterface::RenderMode2D, int multiViewCount=0)
QMultiHash< QVector< quint32 >, QRhiShaderResourceBindings * > srbPool
QHash< GraphicsPipelineStateKey, QRhiGraphicsPipeline * > pipelineCache
ShaderManager(QSGDefaultRenderContext *ctx)
QVector< quint32 > srbLayoutDescSerializeWorkspace
Shader * prepareMaterialNoRewrite(QSGMaterial *material, const QSGGeometry *geometry=nullptr, QSGRendererInterface::RenderMode renderMode=QSGRendererInterface::RenderMode2D, int multiViewCount=0)
void updateRootTransforms(Node *n, Node *root, const QMatrix4x4 &combined)
void registerWithParentRoot(QSGNode *subRoot, QSGNode *parentRoot)
void visitClipNode(Node *n)
void updateStates(QSGNode *n) override
void visitOpacityNode(Node *n)
void updateRootTransforms(Node *n)
void visitTransformNode(Node *n)
void visitGeometryNode(Node *n)
virtual void visualize()=0
Visualizer(Renderer *renderer)
void setMode(VisualizeMode mode)
virtual void visualizeChangesPrepare(Node *n, uint parentChanges=0)
virtual void prepareVisualize()=0
VisualizeMode mode() const
virtual void releaseResources()=0
QHash< Node *, uint > m_visualizeChangeSet
VisualizeMode m_visualizeMode
const int ZORDER_BUFFER_BINDING
static void qsg_wipeBuffer(Buffer *buffer)
static void rendererToMaterialGraphicsState(QSGMaterialShader::GraphicsPipelineState *dst, GraphicsState *src)
size_t qHash(const GraphicsState &s, size_t seed) noexcept
static QRhiVertexInputLayout calculateVertexInputLayout(const QSGMaterialShader *s, const QSGGeometry *geometry, bool batchable)
static void qsg_addBackOrphanedElements(QDataBuffer< Element * > &orphans, QDataBuffer< Element * > &renderList)
bool operator!=(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) noexcept
const float VIEWPORT_MIN_DEPTH
QSGMaterial::Flag QSGMaterial_FullMatrix
bool qsg_sort_batch_decreasing_order(Batch *a, Batch *b)
QDebug operator<<(QDebug d, const Pt &p)
QDebug operator<<(QDebug d, const Rect &r)
bool operator==(const ShaderKey &a, const ShaderKey &b) noexcept
bool operator==(const GraphicsPipelineStateKey &a, const GraphicsPipelineStateKey &b) noexcept
bool operator!=(const ShaderKey &a, const ShaderKey &b) noexcept
static void qsg_wipeBatch(Batch *batch)
static QRhiSampler * newSampler(QRhi *rhi, const QSGSamplerDescription &desc)
QRhiVertexInputAttribute::Format qsg_vertexInputFormat(const QSGGeometry::Attribute &a)
QRhiGraphicsPipeline::Topology qsg_topology(int geomDrawMode, QRhi *rhi)
QMatrix4x4 qsg_matrixForRoot(Node *node)
bool qsg_sort_batch_increasing_order(Batch *a, Batch *b)
static void qsg_addOrphanedElements(QDataBuffer< Element * > &orphans, const QDataBuffer< Element * > &renderList)
void qsg_setMultiViewFlagsOnMaterial(QSGMaterial *material, int multiViewCount)
const float VIEWPORT_MAX_DEPTH
int qsg_positionAttribute(QSGGeometry *g)
static int size_of_type(int type)
static bool isTranslate(const QMatrix4x4 &m)
static int qsg_countNodesInBatches(const QDataBuffer< Batch * > &batches)
static float calculateElementZOrder(const Element *e, qreal zRange)
static int qsg_fixIndexCount(int iCount, int drawMode)
bool qsg_sort_element_increasing_order(Element *a, Element *b)
static void materialToRendererGraphicsState(GraphicsState *dst, QSGMaterialShader::GraphicsPipelineState *src)
static bool needsBlendConstant(QRhiGraphicsPipeline::BlendFactor f)
const int VERTEX_BUFFER_BINDING
const uint DYNAMIC_VERTEX_INDEX_BUFFER_THRESHOLD
bool hasMaterialWithBlending(QSGGeometryNode *n)
static int qsg_countNodesInBatch(const Batch *batch)
bool operator==(const GraphicsState &a, const GraphicsState &b) noexcept
QRhiCommandBuffer::IndexFormat qsg_indexFormat(const QSGGeometry *geometry)
bool operator!=(const GraphicsState &a, const GraphicsState &b) noexcept
bool qsg_sort_element_decreasing_order(Element *a, Element *b)
size_t qHash(const ShaderKey &k, size_t seed) noexcept
void qsg_dumpShadowRoots(BatchRootInfo *i, int indent)
void qsg_dumpShadowRoots(Node *n)
static bool isScale(const QMatrix4x4 &m)
static bool is2DSafe(const QMatrix4x4 &m)
size_t qHash(const GraphicsPipelineStateKey &k, size_t seed) noexcept
Int aligned(Int v, Int byteAlign)
const quint32 DEFAULT_BUFFER_POOL_SIZE_LIMIT
Q_CORE_EXPORT QDebug operator<<(QDebug debug, QDir::Filters filters)
#define DECLARE_DEBUG_VAR(variable)
#define QSGNODE_DIRTY_PARENT
QT_BEGIN_NAMESPACE int qt_sg_envInt(const char *name, int defaultValue)
#define SHADOWNODE_TRAVERSE(NODE)
#define QSGNODE_TRAVERSE(NODE)
Q_DECLARE_TYPEINFO(QSGBatchRenderer::DrawSet, Q_PRIMITIVE_TYPE)
Q_DECLARE_TYPEINFO(QSGBatchRenderer::GraphicsState, Q_RELOCATABLE_TYPE)
Q_DECLARE_TYPEINFO(QSGBatchRenderer::GraphicsPipelineStateKey, Q_RELOCATABLE_TYPE)
#define QSG_RENDERER_COORD_LIMIT
Q_DECLARE_TYPEINFO(QSGBatchRenderer::RenderPassState, Q_RELOCATABLE_TYPE)
bool geometryWasChanged(QSGGeometryNode *gn)
bool isSafeToBatch() const
void cleanupRemovedElements()
BatchCompatibility isMaterialCompatible(Element *e) const
bool isTranslateOnlyToRoot() const
StencilClipState stencilClipState
QDataBuffer< DrawSet > drawSets
uint nonDynamicChangeCount
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
QSGGeometry::DrawingMode drawMode
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)
void map(const QMatrix4x4 &m)
bool isOutsideFloatRange() const
bool intersects(const Rect &r)
void operator|=(const Rect &r)
RenderNodeElement(QSGRenderNode *rn)
QSGRenderNode * renderNode
bool stencilEnabled() const override
QRect scissorRect() const override
const QMatrix4x4 * projectionMatrix() const override
const QRegion * clipRegion() const override
bool scissorEnabled() const override
int stencilValue() const override
const QMatrix4x4 * m_projectionMatrix
QRhiDepthStencilClearValue dsClear
QSGRendererInterface::RenderMode renderMode
QSGMaterialShader * materialShader
QRhiVertexInputLayout inputLayout
QVarLengthArray< QRhiShaderStage, 2 > stages
QRhiCommandBuffer::IndexFormat indexFormat
QRhiShaderResourceBindings * srb
QDataBuffer< StencilDrawCall > drawCalls