Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. DrawPixmapFragments on OpenGL crash when passing in large data size
Forum Updated to NodeBB v4.3 + New Features

DrawPixmapFragments on OpenGL crash when passing in large data size

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 850 Views 2 Watching
  • 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.
  • S Offline
    S Offline
    Sivan
    wrote on last edited by Sivan
    #1

    Hi all,

    I have tried using drawPixmapFragments on QOpenGLWidget to render pixmaps in batch and came upon this crash when I send a pretty large data count right after a small data count.

    Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
    Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000114404000
    Exception Note:        EXC_CORPSE_NOTIFY
    
    Termination Signal:    Segmentation fault: 11
    Termination Reason:    Namespace SIGNAL, Code 0xb
    Terminating Process:   exc handler [0]
    
    VM Regions Near 0x114404000:
        MALLOC_LARGE           0000000114381000-00000001143db000 [  360K] rw-/rwx SM=COW  
    --> 
        MALLOC_LARGE           000000011441b000-000000011451b000 [ 1024K] rw-/rwx SM=COW  
    
    Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
    0   ???                           	0x00000001149db12d 0 + 4640846125
    1   GLEngine                      	0x00007fffd8605c60 glDrawArrays_IMM_Exec + 811
    2   libQt5Gui_debug.5.dylib       	0x000000010af8e143 QOpenGLFunctions::glDrawArrays(unsigned int, int, int) + 99
    3   libQt5Gui_debug.5.dylib       	0x000000010af95e3c QOpenGL2PaintEngineExPrivate::drawPixmapFragments(QPainter::PixmapFragment const*, int, QPixmap const&, QFlags<QPainter::PixmapFragmentHint>) + 2700
    4   libQt5Gui_debug.5.dylib       	0x000000010af9539a QOpenGL2PaintEngineEx::drawPixmapFragments(QPainter::PixmapFragment const*, int, QPixmap const&, QFlags<QPainter::PixmapFragmentHint>) + 298
    5   libQt5Gui_debug.5.dylib       	0x000000010aeaecef QPainter::drawPixmapFragments(QPainter::PixmapFragment const*, int, QPixmap const&, QFlags<QPainter::PixmapFragmentHint>) + 543
    
    

    Here is the example code of what I mean. The below code doesn't make sense. But in actual, I can confirm that I am calling drawPixmapFragments function back to back with valid data, correct size and a valid pixmaps. The only difference is the data size and the pixmap itself.

    typedef QVarLengthArray<QPainter::PixmapFragment, 9> QPixmapFragmentsArray;
    static void s_AppendFragments(const QRect& pixmapRect, const QRectF& rcDest,
                                  QPixmapFragmentsArray& pixmapFragmentArray, int num)
    {
        for (int i = 0; i < num; ++i)
        {
            QPainter::PixmapFragment d;
            d.opacity = 1.0;
            d.rotation = 0.0;
            d.sourceLeft = pixmapRect.left();
            d.sourceTop = pixmapRect.top();
            d.width = pixmapRect.width();
            d.height = pixmapRect.height();
            d.scaleX = rcDest.width() / d.width;
            d.scaleY = rcDest.height() / d.height;
            d.y = rcDest.center().y();
            d.x = rcDest.center().x();
            pixmapFragmentArray.append(d);
        }
    }
    
    static void TestFunc(QPainter* painter, const QPixmap& pixmap1, const QPixmap& pixmap2) // called from paint
    {
        QPixmapFragmentsArray data1;
        QPixmapFragmentsArray data2;
        s_AppendFragments(pixmap1.rect(), QRectF(10, 10, 50, 50), data1, 5940);
        s_AppendFragments(pixmap2.rect(), QRectF(10, 10, 50, 50), data2, 35640);
    
        if (!data1.isEmpty())
        {
            painter->drawPixmapFragments(data1.data(), data1.size(), pixmap1);
        }
    
        if (!data2.isEmpty())
        {
            painter->drawPixmapFragments(data2.data(), data2.size(), pixmap2); 
        }
    }
    

    I am on MacOS Sierra (10.12.2)
    Qt 5.4.1

    Thanks in advance :)

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      What kind of data size are you trying to manipulate ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • S Offline
        S Offline
        Sivan
        wrote on last edited by Sivan
        #3

        @SGaist , Sorry, I am not getting your question. The first call to drawPixmapFragments is being fed with an array of PixmapFragment of size 5940, and the second call with size of 35640.

        I kind of doubt the QDataBuffer that is used by QOpenGL2PEXVertexArray in QOpenGLPaintEngine which will try to reserve memory using realloc when it is adding vertex. But I am really not sure in this. The crash happens when the second call give a pretty large size of array as compared to the first call. If the second call has just slightly higher array size as compared to the first, then I will see some artifact in drawing for that one frame. However, if the first call itself was giving the large array size, then there is no problem.

        1 Reply Last reply
        0
        • S Offline
          S Offline
          Sivan
          wrote on last edited by
          #4

          With the help of a friend, I found out that the issue is indeed in Qt's OpenGLPaintEngine. When we try to realloc a bigger data size than the previous one, realloc might be giving a buffer pointed to different memory address. However, in QOpenGL2PaintEngineExPrivate::transferMode, if the mode are the same back to back, then it did not bother to update the vertex attribute pointer to the new buffer address. Should I raise a bug?

          jsulmJ 1 Reply Last reply
          0
          • S Sivan

            With the help of a friend, I found out that the issue is indeed in Qt's OpenGLPaintEngine. When we try to realloc a bigger data size than the previous one, realloc might be giving a buffer pointed to different memory address. However, in QOpenGL2PaintEngineExPrivate::transferMode, if the mode are the same back to back, then it did not bother to update the vertex attribute pointer to the new buffer address. Should I raise a bug?

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @Sivan Sounds like a bug, you should raise a bug in the bug tracker.

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

            S 1 Reply Last reply
            0
            • jsulmJ jsulm

              @Sivan Sounds like a bug, you should raise a bug in the bug tracker.

              S Offline
              S Offline
              Sivan
              wrote on last edited by
              #6

              @jsulm Sure, here is the link https://bugreports.qt.io/browse/QTBUG-70644

              1 Reply Last reply
              1

              • Login

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