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
QtWS25 Last Chance

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 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?

    jsulmJ 2 Replies Last reply
    0
    • M Offline
      M Offline
      mxyn
      wrote on 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

        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?

        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on 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 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.

          jsulmJ 1 Reply Last reply
          0
          • M mxyn

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

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on 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

              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?

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on 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
              0
              • M Offline
                M Offline
                mxyn
                wrote on 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
                • jsulmJ jsulm

                  @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 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 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
                    0
                    • fcarneyF fcarney

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