Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Segmentation fault when painting a png in updatePaintNode() using QSGTexture
Forum Update on Monday, May 27th 2025

Segmentation fault when painting a png in updatePaintNode() using QSGTexture

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qsgtextureqsgrenderthreadqsggeometryupdatepaintnode
12 Posts 4 Posters 1.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M mxyn
    30 Jun 2020, 07:16

    I'm stumped. I don't know why this code is throwing a segmentation fault. I can't tell where the seg fault is, but I know that it prints up to debug "t8". So it looks like it is exiting updatePaintNode() without a problem.
    I'm ultimately trying to paint multiple png graphics on the scene in different coordinates every frame. So my current baby step is PAINT ONE png item on the scene graph.

    I tried this code in QPainter and it paints fine. So I know I'm accessing it with the right filename.

    updatePaintNode(....)
    {
        QPixmap px1("pics/RadarCarSmall4.png");
        QImage img("pics/RadarCarSmall5.png");
        painter->drawPixmap(10,10,40,40, px1);   // just trying different ways to access and paint
        painter->drawImage(QPointF(50,50), img);  //just trying different way to access and paint
    

    Then I tried this code in updatePaintNode() and it throws a segmentation fault.

     QSGNode *root = static_cast<QSGNode *>(oldNode);
     if(!root) {
         root = new QSGNode;
     }
    qDebug("1");
        root->removeAllChildNodes();
        QSGGeometryNode *n = new QSGGeometryNode();
        QSGGeometry * geo2 = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4);  // create geometry
        geo2->setDrawingMode(QSGGeometry::DrawTriangleFan);
        geo2->vertexDataAsPoint2D()[0].set(100,100);
        geo2->vertexDataAsPoint2D()[1].set(100,150);
        geo2->vertexDataAsPoint2D()[2].set(150,150);
        geo2->vertexDataAsPoint2D()[3].set(150,100);
    qDebug("4");
        QImage img("pics/RadarCarSmall5.png");                   // create texture
        QSGTexture * t = window()->createTextureFromImage(img);
        QSGOpaqueTextureMaterial *testM = new QSGOpaqueTextureMaterial;    
        testM->setTexture(t);                             // set texture
    
    QSGFlatColorMaterial *z2 = new QSGFlatcolorMaterial;
    z2->setColor(Qt::blue);
        n->setMaterial(testM);   // if I replace testM with z2, the segmentation fault goes away.
        n->setGeometry(geo2);
       root->appendChildNode(n);
    qDebug("t8");
    return root
    }
    

    It's very possible I'm not use window() correctly. All I did was #include <QQuickWindow>... I'm not sure if that's the right way to use it?

    J Online
    J Online
    jsulm
    Lifetime Qt Champion
    wrote on 30 Jun 2020, 07:26 last edited by
    #2

    @mxyn said in Segmentation fault when painting a png in updatePaintNode() using QSGTexture:

    it throws a segmentation fault

    Where exactly?

    https://forum.qt.io/topic/113070/qt-code-of-conduct

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mxyn
      wrote on 30 Jun 2020, 07:46 last edited by
      #3

      I updated my previous code so you can see where debug "t8" get's printed. It seems to seg fault after exiting the function.

      J 1 Reply Last reply 30 Jun 2020, 07:47
      0
      • M mxyn
        30 Jun 2020, 07:46

        I updated my previous code so you can see where debug "t8" get's printed. It seems to seg fault after exiting the function.

        J Online
        J Online
        jsulm
        Lifetime Qt Champion
        wrote on 30 Jun 2020, 07:47 last edited by
        #4

        @mxyn Please show stack trace after the crash

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • M mxyn
          30 Jun 2020, 07:16

          I'm stumped. I don't know why this code is throwing a segmentation fault. I can't tell where the seg fault is, but I know that it prints up to debug "t8". So it looks like it is exiting updatePaintNode() without a problem.
          I'm ultimately trying to paint multiple png graphics on the scene in different coordinates every frame. So my current baby step is PAINT ONE png item on the scene graph.

          I tried this code in QPainter and it paints fine. So I know I'm accessing it with the right filename.

          updatePaintNode(....)
          {
              QPixmap px1("pics/RadarCarSmall4.png");
              QImage img("pics/RadarCarSmall5.png");
              painter->drawPixmap(10,10,40,40, px1);   // just trying different ways to access and paint
              painter->drawImage(QPointF(50,50), img);  //just trying different way to access and paint
          

          Then I tried this code in updatePaintNode() and it throws a segmentation fault.

           QSGNode *root = static_cast<QSGNode *>(oldNode);
           if(!root) {
               root = new QSGNode;
           }
          qDebug("1");
              root->removeAllChildNodes();
              QSGGeometryNode *n = new QSGGeometryNode();
              QSGGeometry * geo2 = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4);  // create geometry
              geo2->setDrawingMode(QSGGeometry::DrawTriangleFan);
              geo2->vertexDataAsPoint2D()[0].set(100,100);
              geo2->vertexDataAsPoint2D()[1].set(100,150);
              geo2->vertexDataAsPoint2D()[2].set(150,150);
              geo2->vertexDataAsPoint2D()[3].set(150,100);
          qDebug("4");
              QImage img("pics/RadarCarSmall5.png");                   // create texture
              QSGTexture * t = window()->createTextureFromImage(img);
              QSGOpaqueTextureMaterial *testM = new QSGOpaqueTextureMaterial;    
              testM->setTexture(t);                             // set texture
          
          QSGFlatColorMaterial *z2 = new QSGFlatcolorMaterial;
          z2->setColor(Qt::blue);
              n->setMaterial(testM);   // if I replace testM with z2, the segmentation fault goes away.
              n->setGeometry(geo2);
             root->appendChildNode(n);
          qDebug("t8");
          return root
          }
          

          It's very possible I'm not use window() correctly. All I did was #include <QQuickWindow>... I'm not sure if that's the right way to use it?

          J Online
          J Online
          jsulm
          Lifetime Qt Champion
          wrote on 30 Jun 2020, 07:54 last edited by
          #5

          @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.

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          M 1 Reply Last reply 30 Jun 2020, 08:08
          0
          • M Offline
            M Offline
            mxyn
            wrote on 30 Jun 2020, 07:58 last edited by
            #6

            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

            1 Reply Last reply
            0
            • J jsulm
              30 Jun 2020, 07:54

              @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.

              M Offline
              M Offline
              mxyn
              wrote on 30 Jun 2020, 08:08 last edited by
              #7

              @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.

              1 Reply Last reply
              0
              • fcarneyF Offline
                fcarneyF Offline
                fcarney
                wrote on 30 Jun 2020, 16:34 last edited by
                #8

                @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.

                C++ is a perfectly valid school of magic.

                M 1 Reply Last reply 30 Jun 2020, 17:17
                0
                • fcarneyF fcarney
                  30 Jun 2020, 16:34

                  @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.

                  M Offline
                  M Offline
                  mxyn
                  wrote on 30 Jun 2020, 17:17 last edited by
                  #9

                  @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...

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    mxyn
                    wrote on 1 Jul 2020, 04:35 last edited by
                    #10

                    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 drawn

                    I'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
                    
                    
                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      mxyn
                      wrote on 1 Jul 2020, 06:39 last edited by
                      #11

                      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);
                      
                      1 Reply Last reply
                      2
                      • BilbonSacquetB Offline
                        BilbonSacquetB Offline
                        BilbonSacquet
                        wrote on 16 Mar 2021, 01:22 last edited by
                        #12

                        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.

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved