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