Segmentation fault when painting a png in updatePaintNode() using QSGTexture
-
@mxyn said in Segmentation fault when painting a png in updatePaintNode() using QSGTexture:
it throws a segmentation fault
Where exactly?
-
@mxyn said in Segmentation fault when painting a png in updatePaintNode() using QSGTexture:
QImage img("pics/RadarCarSmall5.png"); // create texture
QSGTexture * t = window()->createTextureFromImage(img);I'm wondering why you're doing this everytime you paint? This can be done once.
-
I would love to! ... How do I pull up the backtrace? I know how to run gdb.... and then backtrace. Is this what you are asking for?
t8
Thread 9 "QThread" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fa8c4d1c0 (LWP 15010)]
0x0000007fb7179418 in QSGBatchRenderer::Renderer::renderUnmergedBatch(QSGBatchRenderer::Batch const*) () from /usr/lib/aarch64-linux-gnu/libQt5Quick.so.5
(gdb) backtrace
#0 0x0000007fb7179418 in QSGBatchRenderer::Renderer::renderUnmergedBatch(QSGBatchRenderer::Batch const*) () at /usr/lib/aarch64-linux-gnu/libQt5Quick.so.5
#1 0x0000007fb7179b60 in QSGBatchRenderer::Renderer::renderBatches() ()
at /usr/lib/aarch64-linux-gnu/libQt5Quick.so.5
#2 0x0000007fb717ed30 in QSGBatchRenderer::Renderer::render() ()
at /usr/lib/aarch64-linux-gnu/libQt5Quick.so.5
#3 0x0000007fb7170eec in QSGRenderer::renderScene(QSGBindable const&) ()
at /usr/lib/aarch64-linux-gnu/libQt5Quick.so.5
#4 0x0000007fb717134c in QSGRenderer::renderScene(unsigned int) ()
at /usr/lib/aarch64-linux-gnu/libQt5Quick.so.5
#5 0x0000007fb71a7cac in QSGDefaultRenderContext::renderNextFrame(QSGRenderer*, unsigned int) ()
at /usr/lib/aarch64-linux-gnu/libQt5Quick.so.5
#6 0x0000007fb7202d7c in QQuickWindowPrivate::renderSceneGraph(QSize const&) ()
at /usr/lib/aarch64-linux-gnu/libQt5Quick.so.5
#7 0x0000007fb72b71e0 in QQuickRenderControl::render() ()
at /usr/lib/aarch64-linux-gnu/libQt5Quick.so.5
#8 0x0000007fa8c550e0 in Worker::doRender(unsigned char*, unsigned char*) (this=0x7fa8c4c370, inFrame=0x8 <error: Cannot access memory at address 0x8>, outFrame=0xffffec00 <error: Cannot access memory at address 0xffffec00>) at gstqoverlay.cpp:344
#9 0x0000007fa8c568c0 in QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1>, QtPrivate::List<unsigned char*, unsigned char*>, bool, bool (Worker::)(unsigned char, unsigned char*)>::call(bool (Worker::)(unsigned char, unsigned char*), Worker*, void**) (arg=0x7f7effbc70, o=<optimized out>, f=<optimized out>) at /usr/include/aarch64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:136 -
@jsulm Short answer is that I'm just trying to get one item on the screen for now. So I figured it's okay to plop this code in while I'm trying to get a handle on how QSGTexture is drawn.
Long answer, I'm drawing radar blips that will be moving across the screen. Each blip will be a different color, and the number of blips may go up or down. It is all represented in a model list that contains the colors and the coords of the blips. The model list will also be growing or shrinking with the number of blips I need to draw. So I plan to have each blip mapped to a node, and create this node from scratch each time. This is probably not the most efficient way to do it. I just started learning updatePaintNode() stuff 2 days ago. I would love to hear if you have a better idea on how to take advantage of the batch processing power of updatePaintNode().
In fact I had made another post hereasking people to give me their opinion on how to make another updatePaintNode() implementation better.
-
@mxyn said in Segmentation fault when painting a png in updatePaintNode() using QSGTexture:
QSGTexture * t = window()->createTextureFromImage(img);
QSGOpaqueTextureMaterial *testM = new QSGOpaqueTextureMaterial;Check for null on anything that is returning a pointer and see if something is failing to be created.
-
@fcarney I tested for NULL, and none of these debugs printed out. meaning the vars aren't null
QImage img("pics/RadarCarSmall5.png"); // create texture QSGTexture * t = window()->createTextureFromImage(img); if(img.isNull()) qdebug("img is null"); if( t == NULL) qDebug( "t is null"); QSGOpaqueTextureMaterial *testM = new QSGOpaqueTextureMaterial; testM.setTexture(t); if( testM == NULL ) qDebug("testM is NULL);
But I do suspect SOMETHING must be wrong with my texture... Not sure what though...
-
I decided to create a SIMPLE project in QTCreator to try to zero in on what's broken in the code. This code draws a triangle and then a rectangle. I tried setting the rectangle material to red. It worked! It tried setting the rectangle material to a texture, it failed! The guilty lines are:
//test->setMaterial(m2); // makes a red rectangle
test->setMaterial(tm); // nothing gets drawnI'm hoping someone could try this code on their QTCreator and see if they have the same problem?
qquickcustomitem.cpp
#include "qquickcustomitem.h" #include <QSGGeometry> #include <QSGGeometryNode> #include <QSGFlatColorMaterial> #include <QDebug> #include <QImage> #include <QQuickWindow> #include <QSGOpaqueTextureMaterial> #include <QSGSimpleRectNode> QQuickCustomItem::QQuickCustomItem(QQuickItem *parent) : QQuickItem(parent), m_color(Qt::red), m_needUpdate(true) { setFlag(QQuickItem::ItemHasContents); } QColor QQuickCustomItem::color() const { return m_color; } void QQuickCustomItem::setColor(const QColor &color) { if(m_color != color) { m_color = color; m_needUpdate = true; update(); colorChanged(); } } QSGNode *QQuickCustomItem::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *updatePaintNodeData) { Q_UNUSED(updatePaintNodeData) QSGGeometryNode *root = static_cast<QSGGeometryNode *>(oldNode); if(!root) { root = new QSGGeometryNode; QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 3); geometry->setDrawingMode(GL_TRIANGLE_FAN); geometry->vertexDataAsPoint2D()[0].set(width() / 2, 0); geometry->vertexDataAsPoint2D()[1].set(width(), height()); geometry->vertexDataAsPoint2D()[2].set(0, height()); root->setGeometry(geometry); root->setFlag(QSGNode::OwnsGeometry); root->setFlag(QSGNode::OwnsMaterial); } if(m_needUpdate) { QSGFlatColorMaterial *material = new QSGFlatColorMaterial; material->setColor(m_color); root->setMaterial(material); m_needUpdate = false; } QSGGeometryNode *test = new QSGGeometryNode; QSGGeometry *geometry2 = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4); geometry2->setDrawingMode(QSGGeometry::DrawTriangleFan); geometry2->vertexDataAsPoint2D()[0].set(100,100); geometry2->vertexDataAsPoint2D()[1].set(100,150); geometry2->vertexDataAsPoint2D()[2].set(150, 150); geometry2->vertexDataAsPoint2D()[3].set(150, 100); QImage img; bool state = img.load(":/scenegraph/customgeometry/radarcar.png"); QSGTexture * t = window()->createTextureFromImage(img); QSGOpaqueTextureMaterial *tm = new QSGOpaqueTextureMaterial; tm->setTexture(t); QSGFlatColorMaterial *m2 = new QSGFlatColorMaterial; m2->setColor(Qt::red); test->setGeometry(geometry2); //test->setMaterial(m2); // makes a red rectangle test->setMaterial(tm); // nothing gets drawn root->appendChildNode(test); return root; }
qquickcustomitem.h
#ifndef QQUICKCUSTOMITEM_H #define QQUICKCUSTOMITEM_H #include <QObject> #include <QQuickItem> #include <QColor> class QQuickCustomItem : public QQuickItem { Q_OBJECT Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) public: QQuickCustomItem(QQuickItem *parent = Q_NULLPTR); protected: QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData); QColor color() const; void setColor(const QColor &color); private: QColor m_color; bool m_needUpdate; signals: void colorChanged(); }; #endif // QQUICKCUSTOMITEM_H
-
I found the problem. I should not be using QSGGeometryNode. I should be using QSGSimpleTextureNode.
QSGSimpleTextureNode *test = new QSGSimpleTextureNode; QImage img; bool state = img.load(":/scenegraph/customgeometry/radarcar.png"); QSGTexture * t = window()->createTextureFromImage(img); test->setTexture(t); test->setRect(10, 10, 30, 30);
-
QSGGeometry * geo2 = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4); // create geometry
The crash is due to the 2D point which is not enough to hold the texture, the call with QSGGeometry::defaultAttributes_TexturedPoint2D() (QSGGeometry::TexturedPoint2D) will solve the issue.