11#include <QtCore/QElapsedTimer>
12#include <QtCore/QtNumeric>
14#include <QtGui/QGuiApplication>
16#include <private/qnumeric_p.h>
21#include <QtQuick/private/qsgnode_p.h>
32#define DECLARE_DEBUG_VAR(variable)
33 static bool debug_ ## variable()
34 { static bool value = qgetenv("QSG_RENDERER_DEBUG").contains(QT_STRINGIFY(variable)); return value; }
45#undef DECLARE_DEBUG_VAR
47#define QSGNODE_TRAVERSE(NODE) for (QSGNode *child = NODE->firstChild(); child; child = child->nextSibling())
48#define SHADOWNODE_TRAVERSE(NODE) for (Node *child = NODE->firstChild(); child; child = child->sibling())
52 static int sizes[] = {
54 sizeof(
unsigned char),
56 sizeof(
unsigned short),
65 Q_ASSERT(type >= QSGGeometry::ByteType && type <= QSGGeometry::DoubleType);
66 return sizes[type - QSGGeometry::ByteType];
76static bool isTranslate(
const QMatrix4x4 &m) {
return m.flags() <= QMatrix4x4::Translation; }
77static bool isScale(
const QMatrix4x4 &m) {
return m.flags() <= QMatrix4x4::Scale; }
78static bool is2DSafe(
const QMatrix4x4 &m) {
return m.flags() < QMatrix4x4::Rotation; }
94 return (v + byteAlign - 1) & ~(byteAlign - 1);
100 case QSGGeometry::FloatType:
101 if (a.tupleSize == 4)
102 return QRhiVertexInputAttribute::Float4;
103 if (a.tupleSize == 3)
104 return QRhiVertexInputAttribute::Float3;
105 if (a.tupleSize == 2)
106 return QRhiVertexInputAttribute::Float2;
107 if (a.tupleSize == 1)
108 return QRhiVertexInputAttribute::Float;
110 case QSGGeometry::UnsignedByteType:
111 if (a.tupleSize == 4)
112 return QRhiVertexInputAttribute::UNormByte4;
113 if (a.tupleSize == 2)
114 return QRhiVertexInputAttribute::UNormByte2;
115 if (a.tupleSize == 1)
116 return QRhiVertexInputAttribute::UNormByte;
121 qWarning(
"Unsupported attribute type 0x%x with %d components", a.type, a.tupleSize);
122 Q_UNREACHABLE_RETURN(QRhiVertexInputAttribute::Float);
128 const QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s);
129 if (!sd->vertexShader) {
130 qWarning(
"No vertex shader in QSGMaterialShader %p", s);
131 return QRhiVertexInputLayout();
134 const int attrCount = geometry->attributeCount();
135 QVarLengthArray<QRhiVertexInputAttribute, 8> inputAttributes;
136 inputAttributes.reserve(attrCount + 1);
138 for (
int i = 0; i < attrCount; ++i) {
139 const QSGGeometry::Attribute &a = geometry->attributes()[i];
140 if (!sd->vertexShader->vertexInputLocations.contains(a.position)) {
141 qWarning(
"Vertex input %d is present in material but not in shader. This is wrong.",
144 inputAttributes.append(QRhiVertexInputAttribute(
VERTEX_BUFFER_BINDING, a.position, qsg_vertexInputFormat(a), offset));
145 offset += a.tupleSize * size_of_type(a.type);
148 inputAttributes.append(QRhiVertexInputAttribute(
ZORDER_BUFFER_BINDING, sd->vertexShader->qt_order_attrib_location,
149 QRhiVertexInputAttribute::Float, 0));
153 QVarLengthArray<QRhiVertexInputBinding, 2> inputBindings;
154 inputBindings.append(QRhiVertexInputBinding(geometry->sizeOfVertex()));
156 inputBindings.append(QRhiVertexInputBinding(
sizeof(
float)));
159 inputLayout.setBindings(inputBindings.cbegin(), inputBindings.cend());
160 inputLayout.setAttributes(inputAttributes.cbegin(), inputAttributes.cend());
167 switch (geometry->indexType()) {
168 case QSGGeometry::UnsignedShortType:
169 return QRhiCommandBuffer::IndexUInt16;
171 case QSGGeometry::UnsignedIntType:
172 return QRhiCommandBuffer::IndexUInt32;
175 Q_UNREACHABLE_RETURN(QRhiCommandBuffer::IndexUInt16);
181 QRhiGraphicsPipeline::Topology topology = QRhiGraphicsPipeline::Triangles;
182 switch (geomDrawMode) {
183 case QSGGeometry::DrawPoints:
184 topology = QRhiGraphicsPipeline::Points;
186 case QSGGeometry::DrawLines:
187 topology = QRhiGraphicsPipeline::Lines;
189 case QSGGeometry::DrawLineStrip:
190 topology = QRhiGraphicsPipeline::LineStrip;
192 case QSGGeometry::DrawTriangles:
193 topology = QRhiGraphicsPipeline::Triangles;
195 case QSGGeometry::DrawTriangleStrip:
196 topology = QRhiGraphicsPipeline::TriangleStrip;
198 case QSGGeometry::DrawTriangleFan:
200 static bool triangleFanSupported =
false;
201 static bool triangleFanSupportChecked =
false;
202 if (!triangleFanSupportChecked) {
203 triangleFanSupportChecked =
true;
204 triangleFanSupported = rhi->isFeatureSupported(QRhi::TriangleFanTopology);
206 if (triangleFanSupported) {
207 topology = QRhiGraphicsPipeline::TriangleFan;
213 qWarning(
"Primitive topology 0x%x not supported", geomDrawMode);
221 material->setFlag(QSGMaterial::MultiView2, multiViewCount == 2);
222 material->setFlag(QSGMaterial::MultiView3, multiViewCount == 3);
223 material->setFlag(QSGMaterial::MultiView4, multiViewCount == 4);
227 const QSGGeometry *geometry,
228 QSGRendererInterface::RenderMode renderMode,
233 QSGMaterialType *type = material->type();
234 ShaderKey key = { type, renderMode, multiViewCount };
235 Shader *shader = rewrittenShaders.value(key,
nullptr);
240 QSGMaterialShader *s =
static_cast<QSGMaterialShader *>(material->createShader(renderMode));
241 context->initializeRhiShader(s, QShader::BatchableVertexShader);
242 shader->materialShader = s;
243 shader->inputLayout = calculateVertexInputLayout(s, geometry,
true);
244 QSGMaterialShaderPrivate *sD = QSGMaterialShaderPrivate::get(s);
246 { QRhiShaderStage::Vertex, sD->shader(QShader::VertexStage), QShader::BatchableVertexShader },
247 { QRhiShaderStage::Fragment, sD->shader(QShader::FragmentStage) }
250 shader->lastOpacity = 0;
252 rewrittenShaders[key] = shader;
256ShaderManager::Shader *
ShaderManager::prepareMaterialNoRewrite(QSGMaterial *material,
257 const QSGGeometry *geometry,
258 QSGRendererInterface::RenderMode renderMode,
263 QSGMaterialType *type = material->type();
264 ShaderKey key = { type, renderMode, multiViewCount };
265 Shader *shader = stockShaders.value(key,
nullptr);
270 QSGMaterialShader *s =
static_cast<QSGMaterialShader *>(material->createShader(renderMode));
271 context->initializeRhiShader(s, QShader::StandardShader);
272 shader->materialShader = s;
273 shader->inputLayout = calculateVertexInputLayout(s, geometry,
false);
274 QSGMaterialShaderPrivate *sD = QSGMaterialShaderPrivate::get(s);
276 { QRhiShaderStage::Vertex, sD->shader(QShader::VertexStage) },
277 { QRhiShaderStage::Fragment, sD->shader(QShader::FragmentStage) }
280 shader->lastOpacity = 0;
282 stockShaders[key] = shader;
289 qDeleteAll(stockShaders);
290 stockShaders.clear();
291 qDeleteAll(rewrittenShaders);
292 rewrittenShaders.clear();
294 qDeleteAll(pipelineCache);
295 pipelineCache.clear();
303 for (ShaderManager::Shader *sms : std::as_const(stockShaders)) {
304 QSGMaterialShader *s = sms->materialShader;
306 QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s);
307 sd->clearCachedRendererData();
310 for (ShaderManager::Shader *sms : std::as_const(rewrittenShaders)) {
311 QSGMaterialShader *s = sms->materialShader;
313 QSGMaterialShaderPrivate *sd = QSGMaterialShaderPrivate::get(s);
314 sd->clearCachedRendererData();
321 static int extraIndent = 0;
324 QByteArray ind(indent + extraIndent + 10,
' ');
327 qDebug(
"%s - no info", ind.constData());
330 for (QSet<Node *>::const_iterator it = i->subRoots.constBegin();
331 it != i->subRoots.constEnd(); ++it) {
332 qDebug() << ind.constData() <<
"-" << *it;
333 qsg_dumpShadowRoots((*it)->rootInfo(), indent);
342#ifndef QT_NO_DEBUG_OUTPUT
343 static int indent = 0;
346 QByteArray ind(indent,
' ');
348 if (n->type() == QSGNode::ClipNodeType || n->isBatchRoot) {
349 qDebug() << ind.constData() <<
"[X]" << n->sgNode << Qt::hex << uint(n->sgNode->flags());
353 d << ind.constData() <<
"[ ]" << n->sgNode << Qt::hex << uint(n->sgNode->flags());
354 if (n->type() == QSGNode::GeometryNodeType)
355 d <<
"order" << Qt::dec << n->element()->order;
373 m_combined_matrix_stack.add(&m_identityMatrix);
374 m_rootMatrices.add(m_identityMatrix);
379 m_current_clip =
nullptr;
382 m_transformChange = 0;
385 Node *sn = renderer->m_nodes.value(n, 0);
388 if (Q_UNLIKELY(debug_roots()))
391 if (Q_UNLIKELY(debug_build())) {
392 qDebug(
"Updater::updateStates()");
393 if (sn->dirtyState & (QSGNode::DirtyNodeAdded << 16))
394 qDebug(
" - nodes have been added");
395 if (sn->dirtyState & (QSGNode::DirtyMatrix << 16))
396 qDebug(
" - transforms have changed");
397 if (sn->dirtyState & (QSGNode::DirtyOpacity << 16))
398 qDebug(
" - opacity has changed");
399 if (uint(sn->dirtyState) & uint(QSGNode::DirtyForceUpdate << 16))
400 qDebug(
" - forceupdate");
404 renderer->m_visualizer->visualizeChangesPrepare(sn);
411 if (m_added == 0 && n->dirtyState == 0 && m_force_update == 0 && m_transformChange == 0 && m_opacityChange == 0)
415 if (n->dirtyState & QSGNode::DirtyNodeAdded)
418 int force = m_force_update;
419 if (n->dirtyState & QSGNode::DirtyForceUpdate)
423 case QSGNode::OpacityNodeType:
426 case QSGNode::TransformNodeType:
429 case QSGNode::GeometryNodeType:
432 case QSGNode::ClipNodeType:
435 case QSGNode::RenderNodeType:
437 n->renderNodeElement()->root = m_roots.last();
445 m_force_update = force;
453 QSGClipNode *cn =
static_cast<QSGClipNode *>(n->sgNode);
455 if (m_roots.last() && m_added > 0)
456 renderer->registerBatchRoot(n, m_roots.last());
458 cn->setRendererClipList(m_current_clip);
461 m_rootMatrices.add(m_rootMatrices.last() * *m_combined_matrix_stack.last());
462 extra->matrix = m_rootMatrices.last();
463 cn->setRendererMatrix(&extra->matrix);
464 m_combined_matrix_stack << &m_identityMatrix;
468 m_current_clip = cn->clipList();
469 m_rootMatrices.pop_back();
470 m_combined_matrix_stack.pop_back();
476 QSGOpacityNode *on =
static_cast<QSGOpacityNode *>(n->sgNode);
478 qreal combined = m_opacity_stack.last() * on->opacity();
479 on->setCombinedOpacity(combined);
480 m_opacity_stack.add(combined);
482 if (m_added == 0 && n->dirtyState & QSGNode::DirtyOpacity) {
483 bool was = n->isOpaque;
486 renderer->m_rebuild = Renderer::FullRebuild;
498 m_opacity_stack.pop_back();
503 bool popMatrixStack =
false;
504 bool popRootStack =
false;
505 bool dirty = n->dirtyState & QSGNode::DirtyMatrix;
507 QSGTransformNode *tn =
static_cast<QSGTransformNode *>(n->sgNode);
509 if (n->isBatchRoot) {
510 if (m_added > 0 && m_roots.last())
511 renderer->registerBatchRoot(n, m_roots.last());
512 tn->setCombinedMatrix(m_rootMatrices.last() * *m_combined_matrix_stack.last() * tn->matrix());
517 if (!n->becameBatchRoot && m_added == 0 && m_force_update == 0 && m_opacityChange == 0 && dirty && (n->dirtyState & ~QSGNode::DirtyMatrix) == 0) {
519 for (QSet<Node *>::const_iterator it = info->subRoots.constBegin();
520 it != info->subRoots.constEnd(); ++it) {
526 n->becameBatchRoot =
false;
528 m_combined_matrix_stack.add(&m_identityMatrix);
530 m_rootMatrices.add(tn->combinedMatrix());
532 popMatrixStack =
true;
534 }
else if (!tn->matrix().isIdentity()) {
535 tn->setCombinedMatrix(*m_combined_matrix_stack.last() * tn->matrix());
536 m_combined_matrix_stack.add(&tn->combinedMatrix());
537 popMatrixStack =
true;
539 tn->setCombinedMatrix(*m_combined_matrix_stack.last());
550 m_combined_matrix_stack.pop_back();
553 m_rootMatrices.pop_back();
559 QSGGeometryNode *gn =
static_cast<QSGGeometryNode *>(n->sgNode);
561 gn->setRendererMatrix(m_combined_matrix_stack.last());
562 gn->setRendererClipList(m_current_clip);
563 gn->setInheritedOpacity(m_opacity_stack.last());
567 e->root = m_roots.last();
568 e->translateOnlyToRoot = isTranslate(*gn->matrix());
572 while (info !=
nullptr) {
575 renderer->m_rebuild |= Renderer::BuildRenderLists;
577 renderer->m_rebuild |= Renderer::BuildRenderListsForTaggedRoots;
578 renderer->m_taggedRoots << e
->root;
586 renderer->m_rebuild |= Renderer::FullRebuild;
589 if (m_transformChange) {
591 e->translateOnlyToRoot = isTranslate(*gn->matrix());
593 if (m_opacityChange) {
596 renderer->invalidateBatchAndOverlappingRenderOrders(e
->batch);
610 if (n->type() == QSGNode::TransformNodeType)
611 m =
static_cast<QSGTransformNode *>(n->sgNode)->matrix() * m;
617 if (node->type() == QSGNode::ClipNodeType) {
618 static_cast<ClipBatchRootInfo *>(info)->matrix = m;
620 Q_ASSERT(node->type() == QSGNode::TransformNodeType);
621 static_cast<QSGTransformNode *>(node->sgNode)->setCombinedMatrix(m);
624 for (QSet<Node *>::const_iterator it = info->subRoots.constBegin();
625 it != info->subRoots.constEnd(); ++it) {
633 for (
int a=0; a<g->attributeCount(); ++a) {
634 const QSGGeometry::Attribute &attr = g->attributes()[a];
635 if (attr.isVertexCoordinate && attr.tupleSize == 2 && attr.type == QSGGeometry::FloatType) {
638 vaOffset += attr.tupleSize * size_of_type(attr.type);
646 const float *m = matrix.constData();
647 if (isScale(matrix)) {
667 set(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
677 Q_ASSERT(!boundsComputed);
678 boundsComputed =
true;
680 QSGGeometry *g = node->geometry();
681 int offset = qsg_positionAttribute(g);
684 bounds.set(-FLT_MAX, -FLT_MAX, FLT_MAX, FLT_MAX);
688 bounds.set(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
689 char *vd = (
char *) g->vertexData() + offset;
690 for (
int i=0; i<g->vertexCount(); ++i) {
692 vd += g->sizeOfVertex();
694 bounds.map(*node->matrix());
696 if (!qt_is_finite(bounds.tl.x) || bounds.tl.x == FLT_MAX)
697 bounds.tl.x = -FLT_MAX;
698 if (!qt_is_finite(bounds.tl.y) || bounds.tl.y == FLT_MAX)
699 bounds.tl.y = -FLT_MAX;
700 if (!qt_is_finite(bounds.br.x) || bounds.br.x == -FLT_MAX)
701 bounds.br.x = FLT_MAX;
702 if (!qt_is_finite(bounds.br.y) || bounds.br.y == -FLT_MAX)
703 bounds.br.y = FLT_MAX;
708 boundsOutsideFloatRange = bounds.isOutsideFloatRange();
715 while (n && (n == e || n->removed))
723 QSGMaterial *m = e->node->activeMaterial();
724 QSGMaterial *nm = n->node->activeMaterial();
725 return (nm->type() == m->type() && nm->viewCount() == m->viewCount() && nm->compare(m) == 0)
731
732
733
734
738 Q_ASSERT_X(e,
"Batch::geometryWasChanged",
"Batch is expected to 'valid' at this time");
740 while (e && (e->node == gn || e->removed))
742 if (!e || e->node->geometry()->attributes() == gn->geometry()->attributes()) {
776
777
778
797 only &= e->translateOnlyToRoot;
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
823 if (e->boundsOutsideFloatRange)
825 if (!is2DSafe(*e->node->matrix()))
846 for (
int i=0; i<batches.size(); ++i) {
847 sum += qsg_countNodesInBatch(batches.at(i));
874#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
919 qDebug(
"Batch thresholds: nodes: %d vertices: %d srb pool: %d buffer pool: %d",
938 qsg_wipeBuffer(&batch->vbo);
939 qsg_wipeBuffer(&batch->ibo);
941 batch->stencilClipState.reset();
1367#ifndef QT_NO_DEBUG_OUTPUT
1372 debug <<
"Geometry";
1374 debug <<
"Material";
1384 debug <<
"SubtreeBlocked";
1386 debug <<
"ForceUpdate";
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1599 for (
int i=0; i<renderList.size(); ++i) {
1600 Element *e = renderList.at(i);
1601 if (e && !e->removed) {
1610 for (
int i=0; i<orphans.size(); ++i) {
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1718#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
1747
1748
1785 for (
int j =
i - 1;
j >= 0; --
j) {
1827#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
1841
1842
1843
1844
1845
1846
1847
1848
1849
1903#if !defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
1938
1939
1940
1941
1958 case QSGGeometry::DrawTriangleStrip:
1965 case QSGGeometry::DrawLines:
1967 return iCount - (iCount % 2);
1968 case QSGGeometry::DrawTriangles:
1970 return iCount - (iCount % 3);
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
2099 if (node->type() == QSGNode::TransformNodeType)
2100 return static_cast<QSGTransformNode *>(node->sgNode)->combinedMatrix();
2101 Q_ASSERT(node->type() == QSGNode::ClipNodeType);
2102 QSGClipNode *c =
static_cast<QSGClipNode *>(node->sgNode);
2103 return *c->matrix();
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2269 Q_ASSERT_X(
false,
"uploadBatch (unmerged)",
"uint index with ushort effective index - cannot happen");
2277#ifndef QT_NO_DEBUG_OUTPUT
2283 dump <<
" --- " <<
i <<
": ";
2293 dump << *(
const float *)(
vd +
offset +
t *
sizeof(
float)) <<
" ";
2297 dump << *(
const unsigned char *)(
vd +
offset +
t *
sizeof(
unsigned char)) <<
" ";
2395 qWarning(
"Failed to build stencil clip pipeline");
2514 qWarning(
"Failed to build stencil clip vertex buffer");
2532 qWarning(
"Failed to build stencil clip index buffer");
2550 qWarning(
"Failed to build stencil clip uniform buffer");
2563 qWarning(
"Failed to build stencil clip srb");
2587 qWarning(
"updateClipState: Clip list entries have different primitive topologies, this is not currently supported.");
2589 qWarning(
"updateClipState: Clip list entries have different vertex input layouts, this is must not happen.");
2671 }
else if (
i == 1) {
2700 return f == QRhiGraphicsPipeline::ConstantColor
2701 || f == QRhiGraphicsPipeline::OneMinusConstantColor
2702 || f == QRhiGraphicsPipeline::ConstantAlpha
2703 || f == QRhiGraphicsPipeline::OneMinusConstantAlpha;
2815 qWarning(
"Failed to build graphics pipeline state");
2828static QRhiSampler *
newSampler(QRhi *rhi,
const QSGSamplerDescription &desc)
2830 QRhiSampler::Filter magFilter;
2831 QRhiSampler::Filter minFilter;
2832 QRhiSampler::Filter mipmapMode;
2833 QRhiSampler::AddressMode u;
2834 QRhiSampler::AddressMode v;
2836 switch (desc.filtering) {
2837 case QSGTexture::None:
2839 case QSGTexture::Nearest:
2840 magFilter = minFilter = QRhiSampler::Nearest;
2842 case QSGTexture::Linear:
2843 magFilter = minFilter = QRhiSampler::Linear;
2847 magFilter = minFilter = QRhiSampler::Nearest;
2851 switch (desc.mipmapFiltering) {
2852 case QSGTexture::None:
2853 mipmapMode = QRhiSampler::None;
2855 case QSGTexture::Nearest:
2856 mipmapMode = QRhiSampler::Nearest;
2858 case QSGTexture::Linear:
2859 mipmapMode = QRhiSampler::Linear;
2863 mipmapMode = QRhiSampler::None;
2867 switch (desc.horizontalWrap) {
2868 case QSGTexture::Repeat:
2869 u = QRhiSampler::Repeat;
2871 case QSGTexture::ClampToEdge:
2872 u = QRhiSampler::ClampToEdge;
2874 case QSGTexture::MirroredRepeat:
2875 u = QRhiSampler::Mirror;
2879 u = QRhiSampler::ClampToEdge;
2883 switch (desc.verticalWrap) {
2884 case QSGTexture::Repeat:
2885 v = QRhiSampler::Repeat;
2887 case QSGTexture::ClampToEdge:
2888 v = QRhiSampler::ClampToEdge;
2890 case QSGTexture::MirroredRepeat:
2891 v = QRhiSampler::Mirror;
2895 v = QRhiSampler::ClampToEdge;
2899 return rhi->newSampler(magFilter, minFilter, mipmapMode, u, v);
2923 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::OneMinusSrc1Alpha) ==
int(QRhiGraphicsPipeline::OneMinusSrc1Alpha));
2924 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::BlendOp::Max) ==
int(QRhiGraphicsPipeline::Max));
2925 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::A) ==
int(QRhiGraphicsPipeline::A));
2926 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::CullBack) ==
int(QRhiGraphicsPipeline::Back));
2927 Q_ASSERT(
int(QSGMaterialShader::GraphicsPipelineState::Line) ==
int(QRhiGraphicsPipeline::Line));
2928 dst->srcColor = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->srcColor);
2929 dst->dstColor = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->dstColor);
2937 dst->separateBlendFactors =
false;
2939 dst->srcAlpha = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->srcAlpha);
2940 dst->dstAlpha = QSGMaterialShader::GraphicsPipelineState::BlendFactor(src->dstAlpha);
2942 dst->opColor = QSGMaterialShader::GraphicsPipelineState::BlendOp(src->opColor);
2943 dst->opAlpha = QSGMaterialShader::GraphicsPipelineState::BlendOp(src->opAlpha);
2945 dst->colorWrite = QSGMaterialShader::GraphicsPipelineState::ColorMask(
int(src->colorWrite));
2947 dst->cullMode = QSGMaterialShader::GraphicsPipelineState::CullMode(src->cullMode);
2948 dst->polygonMode = QSGMaterialShader::GraphicsPipelineState::PolygonMode(src->polygonMode);
2952 QSGMaterialShader::GraphicsPipelineState *src)
2955 dst->srcColor = QRhiGraphicsPipeline::BlendFactor(src->srcColor);
2956 dst->dstColor = QRhiGraphicsPipeline::BlendFactor(src->dstColor);
2957 if (src->separateBlendFactors) {
2958 dst->srcAlpha = QRhiGraphicsPipeline::BlendFactor(src->srcAlpha);
2959 dst->dstAlpha = QRhiGraphicsPipeline::BlendFactor(src->dstAlpha);
2961 dst->srcAlpha = dst->srcColor;
2962 dst->dstAlpha = dst->dstColor;
2964 dst->opColor = QRhiGraphicsPipeline::BlendOp(src->opColor);
2965 dst->opAlpha = QRhiGraphicsPipeline::BlendOp(src->opAlpha);
2966 dst->colorWrite = QRhiGraphicsPipeline::ColorMask(
int(src->colorWrite));
2967 dst->cullMode = QRhiGraphicsPipeline::CullMode(src->cullMode);
2968 dst->polygonMode = QRhiGraphicsPipeline::PolygonMode(src->polygonMode);
3019 qWarning(
"No QSGTexture provided from updateSampledImage(). This is wrong.");
3041 qWarning(
"QSGTexture anisotropy levels are not currently supported");
3053 qWarning(
"Failed to build sampler");
3168 Q_ASSERT_X(
false,
"updateMaterialDynamicData",
"No srb action set, this cannot happen");
3208#ifndef QT_NO_DEBUG_OUTPUT
3346 qWarning(
"Line widths other than 1 are not supported by the graphics API");
3354 qWarning(
"Point size is not controllable by QSGGeometry. "
3355 "Set gl_PointSize from the vertex shader instead.");
3728 qWarning(
"prepareRenderPass() called with an already prepared render pass context");
3752 type +=
" renderlists";
3759 qDebug() <<
"Renderer::render()" <<
this <<
type;
3774 qDebug(
"Opaque render lists %s:", (
complete ?
"(complete)" :
"(partial)"));
3779 qDebug(
"Alpha render list %s:",
complete ?
"(complete)" :
"(partial)");
3804 qDebug(
"Opaque Batches:");
3812 qDebug(
"Alpha Batches:");
3955#if defined(QSGBATCHRENDERER_INVALIDATE_WEDGED_NODES)
3997 qWarning(
"recordRenderPass() called without a prepared render pass context");
4054 qDebug(
" -> times: build: %d, prepare(opaque/alpha): %d/%d, sorting: %d, upload(opaque/alpha): %d/%d, record rendering: %d",
4220 else if (
mode ==
"clip")
4222 else if (
mode ==
"overdraw")
4224 else if (
mode ==
"batches")
4226 else if (
mode ==
"changes")
4239 && a.depthFunc == b.depthFunc
4241 && a.srcColor == b.srcColor
4242 && a.dstColor == b.dstColor
4243 && a.srcAlpha == b.srcAlpha
4244 && a.dstAlpha == b.dstAlpha
4245 && a.opColor == b.opColor
4246 && a.opAlpha == b.opAlpha
4247 && a.colorWrite == b.colorWrite
4248 && a.cullMode == b.cullMode
4252 && a.drawMode == b.drawMode
4254 && a.polygonMode == b.polygonMode
4281 return a.state == b.state
4282 && a
.sms->materialShader == b
.sms->materialShader
4283 && a.renderTargetDescription == b.renderTargetDescription
4284 && a.srbLayoutDescription == b.srbLayoutDescription;
4294 return qHash(k.state, seed)
4295 ^ qHash(k.sms->materialShader)
4296 ^ k.extra.renderTargetDescriptionHash
4297 ^ k.extra.srbLayoutDescriptionHash;
4302 return a.type == b.type
4303 && a.renderMode == b.renderMode
4314 return qHash(k.type, seed) ^
int(k.renderMode) ^ k.multiViewCount;
4327#define QSGNODE_DIRTY_PARENT (QSGNode::DirtyNodeAdded
4328 | QSGNode::DirtyOpacity
4329 | QSGNode::DirtyMatrix
4330 | QSGNode::DirtyNodeRemoved)
4335 uint selfDirty = n->dirtyState | parentChanges;
4336 if (n->type() == QSGNode::GeometryNodeType && selfDirty != 0)
4337 m_visualizeChangeSet.insert(n, selfDirty);
4339 visualizeChangesPrepare(child, childDirty);
4347#include "moc_qsgbatchrenderer_p.cpp"
void clearCachedRendererData()
void updateRootTransforms(Node *n, Node *root, const QMatrix4x4 &combined)
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)
Visualizer(Renderer *renderer)
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)
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
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)
bool geometryWasChanged(QSGGeometryNode *gn)
bool isSafeToBatch() const
void cleanupRemovedElements()
BatchCompatibility isMaterialCompatible(Element *e) const
bool isTranslateOnlyToRoot() const
const ShaderManagerShader * sms
BatchRootInfo * rootInfo() const
ClipBatchRootInfo * clipInfo() const
Element * element() const
void operator|=(const Pt &pt)
void set(float left, float top, float right, float bottom)
void map(const QMatrix4x4 &m)
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