Я пытаюсь добиться рендеринга графа с использованием графа сцены Qt.При рендеринге графика всегда происходит обновление для определенного столбца пикселей (пикселей в одном вертикальном столбце), поэтому я создал n дочерних узлов (QSGNode) для корневого узла (здесь n - ширина области визуализации)и для каждого из этих дочерних узлов я создал 6 дочерних узлов (QSGGeometryNode в режиме рисования GL_LINES), по одному для каждого графика на экране.В основном, если ширина области рендеринга равна 100, корневой узел будет иметь в общей сложности 100 * 6 дочерних узлов.Обновление происходит только на небольшом количестве дочерних узлов, после обновления геометрии я помечаю узел как DirtyGeometry.
Выглядит хорошо для меня, пока здесь, но я вижу, что это занимает много процессора, поэтому я попытался отладить с помощью QSG_RENDERER_DEBUG = render, я вижу, что все дочерние узлы отрисовываются снова свызов updatePaintNode вместо определенных, которые я пометил как грязные.
Журнал выглядит следующим образом
Renderer::render() QSGAbstractRenderer(0xf9a5a0) "rebuild: none"
Rendering:
-> Opaque: 6145 nodes in 2 batches...
-> Alpha: 0 nodes in 0 batches...
- 0xf9a910 [ upload] [noclip] [opaque] [ merged] Nodes: 6144
Vertices: 12288 Indices: 12288 root: 0x0
- 0xf9a960 [retained] [noclip] [opaque] [ merged] Nodes: 1
Vertices: 4 Indices: 6 root: 0x0
-> times: build: 0, prepare(opaque/alpha): 0/0, sorting: 0,
upload(opaque/alpha): 0/0, render: 0
Область рендеринга - 1024 * 624 (т.е. 1024 * 6 = 6144 дочерней QSGGeometryузлы).
QSGNode *QSGPlot::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
{
QSGGeometry *geometry = nullptr;
QSGNode* parentNode = nullptr;
if (!oldNode)
{
Q_ASSERT (_wfGenerator == nullptr);
float pixelWidth, pixelHeight;
DisplayInfo::getPixelSize(pixelWidth,pixelHeight);
const QRectF bounds = boundingRect();
float speed = 50.0f;
float gain = 10.0f;
_wfGenerator = new WFGenerator(pixelWidth,pixelHeight, speed,gain,bounds.width(),bounds.height());
parentNode = new QSGNode;
for (size_t columnI = 0; columnI < bounds.width(); columnI++)
{
QSGNode *columnNode = new QSGNode;
parentNode->appendChildNode(columnNode);
createGeometryChildNodes(columnNode, Qt::green, 6);
}
}
else
{
parentNode = static_cast<QSGGeometryNode*>(oldNode);
Q_ASSERT (parentNode->childCount() == boundingRect().width());
}
size_t dirtyColumnCount = 0;
_wfGenerator->generateWF(_columnBuffer, dirtyColumnCount);
for (size_t dirtyColI = 0; dirtyColI < dirtyColumnCount; dirtyColI++)
{
size_t updateCol = _columnBuffer[dirtyColI].columnI;
QSGNode *columnNode = static_cast<QSGNode*>(parentNode->childAtIndex(updateCol));
if (_columnBuffer[dirtyColI].validDirtyYCoordinates != 0)
{
Q_ASSERT (columnNode->childCount() >= _columnBuffer[dirtyColI].validDirtyYCoordinates);
for (auto rowI = 0; rowI < _columnBuffer[dirtyColI].validDirtyYCoordinates; rowI++)
{
QSGGeometryNode *rowNode = static_cast<QSGGeometryNode*>(columnNode->childAtIndex(rowI));
geometry = rowNode->geometry();
geometry->vertexDataAsPoint2D()[0].set(updateCol, _columnBuffer[dirtyColI].dirtyYCoordinates[rowI].y);
geometry->vertexDataAsPoint2D()[1].set(updateCol, _columnBuffer[dirtyColI].dirtyYCoordinates[rowI].y1);
rowNode->markDirty(QSGNode::DirtyGeometry);
}
}
else
{
for (auto rowI = 0; rowI < columnNode->childCount(); rowI++)
{
QSGGeometryNode *rowNode = static_cast<QSGGeometryNode*>(columnNode->childAtIndex(rowI));
geometry = rowNode->geometry();
geometry->vertexDataAsPoint2D()[0].set(updateCol, 0);
geometry->vertexDataAsPoint2D()[1].set(updateCol, 0);
rowNode->markDirty(QSGNode::DirtyGeometry);
}
}
}
return parentNode;
}
void QSGPlot::createGeometryChildNodes(QSGNode *parent, const QColor &color, const size_t &childCount)
{
for (size_t childI = 0; childI < childCount; childI++)
{
QSGGeometryNode *childNode = new QSGGeometryNode;
QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 2);
geometry->setLineWidth(1);
geometry->setDrawingMode(GL_LINES);
childNode->setGeometry(geometry);
childNode->setFlag(QSGNode::OwnsGeometry);
QSGFlatColorMaterial* material = new QSGFlatColorMaterial();
material->setColor(color);
childNode->setMaterial(material);
childNode->setFlag(QSGNode::OwnsMaterial);
parent->appendChildNode(childNode);
}
}
Может кто-нибудь указать, что я делаю неправильно в этой реализации. Найти экранную запись приложения можно здесь.