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 Updated to NodeBB v4.3 + New Features

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.7k 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: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
            • F Offline
              F 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
              • F 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