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 Offline
    M Offline
    mxyn
    wrote on 30 Jun 2020, 07:16 last edited by mxyn
    #1

    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 2 Replies Last reply 30 Jun 2020, 07:26
    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
      • 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 Offline
        J Offline
        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 Offline
            J Offline
            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 Offline
              J Offline
              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