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. Crash using QPainter from secondary thread

Crash using QPainter from secondary thread

Scheduled Pinned Locked Moved General and Desktop
17 Posts 8 Posters 13.5k Views 1 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.
  • B Offline
    B Offline
    bourbon
    wrote on last edited by
    #1

    Hello, I'm trying to draw into a QImage using a QPainter from a secondary thread. As far as I know this should be supported by Qt.
    I get a consistent crash (segfault) deep inside the paint engine, possibly sse related. In the code below, it crashes inside the call to painter.drawLine().
    I'm running XP using Qt 4.7.3 with mingw and QtCreator 2.1.0

    I've managed to produce a small sample which exhibits the issue, could anyone take a look and see if I'm doing anything stupid, or even if you can just reproduce it (it doesn't seem to occur on my vista machine).

    ========== MainWindow.h =========
    @
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QtGui/QMainWindow>
    #include <QThread>
    #include <QWidget>
    #include <QImage>

    class Canvas : public QWidget
    {
    Q_OBJECT
    public:
    Canvas(QWidget* parent=0);

    void drawStuff();

    protected:
    void paintEvent(QPaintEvent *);

    QImage m_image;
    };

    class RenderThread : public QThread
    {
    public:
    RenderThread(Canvas* canvas) : m_canvas(canvas), m_stopping(false) {}

    void run();
    void stop() { m_stopping = true; }

    private:
    Canvas* m_canvas;
    bool m_stopping;
    };

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

    private:
    RenderThread* m_renderThread;
    };

    #endif // MAINWINDOW_H

    =========== MainWindow.cpp ============
    #include "MainWindow.h"
    #include <QPainter>
    #include <QTimer>
    #include <QMutex>

    QMutex g_mutex;

    Canvas::Canvas(QWidget *parent)
    : QWidget(parent),
    m_image(256,256, QImage::Format_ARGB32_Premultiplied)
    {
    }

    void Canvas::drawStuff()
    {
    g_mutex.lock();

    m_image.fill(0xffffffff);

    QPainter painter(&m_image);
    QPen pen(QColor(40,90,180,200));
    pen.setWidthF(12.0f);
    painter.setPen(pen);
    painter.drawLine(QPointF(0,0), QPointF(256,256));

    g_mutex.unlock();
    }

    void Canvas::paintEvent(QPaintEvent *)
    {
    g_mutex.lock();

    QPainter p(this);
    p.drawImage(0,0, m_image);

    g_mutex.unlock();
    }

    void RenderThread::run()
    {
    while(!m_stopping)
    {
    m_canvas->drawStuff();
    msleep(10);
    }
    }

    MainWindow::MainWindow(QWidget parent)
    : QMainWindow(parent)
    {
    Canvas
    canvas = new Canvas(this);
    setCentralWidget(canvas);

    m_renderThread = new RenderThread(canvas);
    m_renderThread->start();
    }

    MainWindow::~MainWindow()
    {
    m_renderThread->stop();
    m_renderThread->wait();

    delete m_renderThread;
    }
    @

    EDIT: please use @-tags for code highlighting, thanks. Gerolf

    1 Reply Last reply
    0
    • F Offline
      F Offline
      Franzk
      wrote on last edited by
      #2

      As far as I remember, QImage: no multithread support, QPixmap: multithread support.

      "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

      http://www.catb.org/~esr/faqs/smart-questions.html

      1 Reply Last reply
      0
      • G Offline
        G Offline
        giesbert
        wrote on last edited by
        #3

        Franzk,

        it should be the other way round:

        bq. Because QImage is a QPaintDevice subclass, QPainter can be used to draw directly onto images. When using QPainter on a QImage, the painting can be performed in another thread than the current GUI thread.

        Nokia Certified Qt Specialist.
        Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

        1 Reply Last reply
        0
        • J Offline
          J Offline
          jim_kaiser
          wrote on last edited by
          #4

          Well... do you get any messages in the application output about the painter? You could try to do the m_image.fill in the constructor maybe? As soon as you create your canvas, I think it generates a paintEvent() or atleast on the setCentralWidget().. and so maybe drawing the m_image with uninitialized data is the problem.. maybe..

          1 Reply Last reply
          0
          • B Offline
            B Offline
            bourbon
            wrote on last edited by
            #5

            There are no messages in the output, and moving the image.fill doesn't seem to make any difference.
            Since it seems to be explicitly supported in the docs, I'm wondering if it's something to do with my local setup, can anyone else reproduce it?

            1 Reply Last reply
            0
            • G Offline
              G Offline
              giesbert
              wrote on last edited by
              #6

              I can reproduce it with win XP and mingw...

              Nokia Certified Qt Specialist.
              Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

              1 Reply Last reply
              0
              • G Offline
                G Offline
                giesbert
                wrote on last edited by
                #7

                Using MSVS2008 and Qt 4.7.0, it works, using Qt 4.7.3 and mingw, it crashes....

                Nokia Certified Qt Specialist.
                Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                1 Reply Last reply
                0
                • J Offline
                  J Offline
                  jim_kaiser
                  wrote on last edited by
                  #8

                  Will try to repro..

                  [Edit: Ubuntu 10.04 Qt SDK 1.1.1 Qt 4.7.4.. works.. no crash.. ]

                  1 Reply Last reply
                  0
                  • B Offline
                    B Offline
                    bourbon
                    wrote on last edited by
                    #9

                    Ah, thanks. That's interesting.

                    1 Reply Last reply
                    0
                    • G Offline
                      G Offline
                      giesbert
                      wrote on last edited by
                      #10

                      Sorry, one mistake, I used 4.7.2.
                      Mingw --> crash, msvs2008 --> works
                      4.7.0 msvs2008 --> works

                      very strange...

                      Nokia Certified Qt Specialist.
                      Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                      1 Reply Last reply
                      0
                      • B Offline
                        B Offline
                        bourbon
                        wrote on last edited by
                        #11

                        Does this sound like something that should be reported on the Qt bugtracker? If so, where do I do that?

                        1 Reply Last reply
                        0
                        • S Offline
                          S Offline
                          steno
                          wrote on last edited by
                          #12

                          "For info on how to post a bug....":http://developer.qt.nokia.com/wiki/ReportingBugsInQt

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            andre
                            wrote on last edited by
                            #13

                            [quote author="bourbon" date="1308069402"]Does this sound like something that should be reported on the Qt bugtracker? If so, where do I do that?[/quote]

                            It does to me. Sounds like a regression, and those are generally taken quite seriously. Don't forget to attach your example to reproduce the issue, link to this topic, and add a tag to this topic with the bug id (QTBUG-#####)

                            1 Reply Last reply
                            0
                            • D Offline
                              D Offline
                              dangelog
                              wrote on last edited by
                              #14

                              The first thing that comes in my mind is that you're not end()ing the painting before releasing the lock, thus you're relying on the QPainter dtor (which will end the painting itself).

                              There's an obvious race condition there, and I'm confident that helgrind would have told you so. Try adding end() there, or switch to QMutexLocker.

                              Software Engineer
                              KDAB (UK) Ltd., a KDAB Group company

                              1 Reply Last reply
                              0
                              • F Offline
                                F Offline
                                Franzk
                                wrote on last edited by
                                #15

                                The latter will probably give cleaner code.

                                "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

                                http://www.catb.org/~esr/faqs/smart-questions.html

                                1 Reply Last reply
                                0
                                • B Offline
                                  B Offline
                                  bourbon
                                  wrote on last edited by
                                  #16

                                  The crash occurs in the very first call to painter.drawLine(), so I don't think it's a race condition.
                                  I didn't realise I shold be calling end(), I've added it but it makes no difference (the code never reaches it).

                                  1 Reply Last reply
                                  0
                                  • M Offline
                                    M Offline
                                    mlangezaal
                                    wrote on last edited by
                                    #17

                                    I have posted the root cause, a small project to reproduce it and a temporary workaround in the Bugtracker for this bug: QTBUG-19886

                                    It is caused by a stack mis-alignment of the newly created thread. It affects the drawing engine which expects 16-byte alignment for the used SSE2 instructions.
                                    It appears to only occur on windows XP. And happens when a QPainter::drawImage is done on a different thread. The stack on the new thread (QThread subclass and started with start()) is NOT 16-bit aligned, and causes a Segmentation Fault on
                                    the MMX instruction PANDN in qdrawhelper_sse2.cpp.

                                    The only (dirty) workaround I can think of is to manually push extra bytes on the stack in case it is not aligned to realign the SP to a 16-byte boundary. And this seems to work quite well, no more crashes!

                                    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