PDA

View Full Version : Qt 5.5 + QwtPlotDirectPainter = Problems on (Mac) OS X?



agarny
13th July 2015, 17:36
Hi,

I have been using QwtPlotDirectPainter for some time with Qt 4.7+ and then Qt 5.x, and it has been working perfectly fine. Now, with the recent release of Qt 5.5, I thought I would update my software to use that newer version of Qt.

It's all working fine on Windows and Linux, but on OS X, I am having problems. Indeed, whenever I call QwtPlotDirectPainter::drawSeries(), there is a high risk of the plotting area becoming completely black. After some digging around, I noticed a thread that led me to call QwtPlotDirectPainter::setAttribute() to set QwtPlotDirectPainter::FullRepaint to true for my direct painter.

Now, I thought I had a winner since it is working fine on OS X 10.10, but it doesn't on (Mac) OS X 10.7, 10.8 and 10.9. In fact, it's even worse than that since it crashes my application. Indeed, after calling QwtPlotDirectPainter::drawSeries(), my application crashes and I get the following messages:


QPainter::begin: A paint device can only be painted by one painter at a time.
QPainter::translate: Painter not active
QPainter::begin: A paint device can only be painted by one painter at a time.
QPainter::save: Painter not active
QPainter::setClipRect: Painter not active
QPainter::save: Painter not active
QPainter::setRenderHint: Painter must be active to set rendering hints
QPainter::setRenderHint: Painter must be active to set rendering hints
QPainter::setPen: Painter not active
QPainter::setPen: Painter not active
QPainter::restore: Unbalanced save/restore
QPainter::save: Painter not active
QPainter::setRenderHint: Painter must be active to set rendering hints
QPainter::setRenderHint: Painter must be active to set rendering hints
QPainter::restore: Unbalanced save/restore
QPainter::restore: Unbalanced save/restore

I tried to figure out where the crash occurs and it would seem that it occurs upon calling plotCanvas->repaint() in QwtPlotDirectPainter::drawSeries(), i.e. here (http://sourceforge.net/p/qwt/code/HEAD/tree/branches/qwt-6.1/src/qwt_plot_directpainter.cpp#l193).

So... any idea why my application crashes on (Mac) OS X 10.7, 10.8 and 10.9, but not on 10.10 (and not on Windows or Linux either)? Otherwise, and interestingly enough, my original issue with the plotting area becoming black only occurs on (Mac) OS X. So, maybe it has something to do with Qt 5.5 (since it didn't use to happen with Qt 5.4.2)?

agarny
14th July 2015, 18:58
FWIW, the aforementioned crash can be avoided by making sure that painter goes out of scope before plotCanvas->repaint() gets called, e.g.



if ( plotCanvas && qwtHasBackingStore( plotCanvas ) )
{
{ // Quick way to make sure that 'paint' goes out of scope before
// plotCanvas->repaint() gets called below (should it get called)
QPainter painter( const_cast<QPixmap *>( plotCanvas->backingStore() ) );

if ( d_data->hasClipping )
painter.setClipRegion( d_data->clipRegion );

qwtRenderItem( &painter, canvasRect, seriesItem, from, to );
}

if ( testAttribute( QwtPlotDirectPainter::FullRepaint ) )
{
plotCanvas->repaint();
return;
}
}


However, if there are many points to draw, then rendering will eventually become very slow on Mac OS X 10.7 (I haven't tried OS X 10.8 and 10.9) while there was no noticeable difference on OS X 10.10, independent of whether QwtPlotDirectPainter::FullRepaint was set to true or not.

Uwe
15th July 2015, 07:25
FWIW, the aforementioned crash can be avoided by making sure that painter goes out of scope before plotCanvas->repaint() gets called, e.g.
I added a painter.end(), what should do the same as your patch - done in all relevant SVN branches.

But this painter is for drawing on the backing store of the plot canvas, while the following repaint should run into a path, where the backing store is painted to the widget. When running into conflicts with having more than one painter for the backing store it seems, that QwtPlotCanvas::paintEvent() runs into a different path, where it also wants to draw to the backingstore. There might be exceptions in combination with resize events, but when this also happens during regular situations, there might be something completely wrong.


However, if there are many points to draw, then rendering will eventually become very slow on Mac OS X 10.7 (I haven't tried OS X 10.8 and 10.9) while there was no noticeable difference on OS X 10.10, independent of whether QwtPlotDirectPainter::FullRepaint was set to true or not.
The all over number of points should be irrelevant as long as you don't run into a replot operation ( f.e. when resizing the plot canvas ). As long as you are drawing incrementally the only relevant parameter is the number of points you are drawing with QwtPlotDirectPainter. In case of using QwtPlotDirectPainter::FullRepaint the number of calls are relevant too: drawing 3x1 point will be way slower than drawing 1x3 points.

But instead of giving up too early I would recommend to spend some time on why you have issues with Qt 5.5 you don't have with Qt 5.4. When comparing the Mac specific code of Qt 5.4 with 5.5 you might be able to identify the difference.
Unfortunately I can't help here much - I don't have a Mac myself.

Uwe

agarny
15th July 2015, 13:40
Ok, I am very puzzled: I am not getting the crash anymore on Mac OS X 10.7 (this being said, your patch cannot harm, so it's still good to have it in).

A couple of days ago, I generated a new release version of my software. From there, I wanted to test it on the different platforms I support and that includes (Mac) OS X 10.7 to 10.10. As I said, my software was working fine on OS X 10.10 while it crashed and generated the messages I provided, and this on (Mac) OS X 10.7, 10.8 and 10.9.

Today, I implemented your fix and generated a new release version of my software, and it's working fine on all the Mac versions that I support. But, out of curiosity, I thought I would try one more time my release version of two days ago and... it's also working fine on Mac OS X 10.7!? In other words, I am not getting any crash while I did two days ago.

The only differences I can think of between today and two days ago are:

I implemented your patch; and
Two days ago, I was running my application on my Mac, but I was 'watching' it on my home PC computer through RealVNC (http://www.realvnc.com/).


Surely, RealVNC (http://www.realvnc.com/) cannot be (indirectly?) responsible for the crash I experienced two days ago?

Whatever the case, I am now running my application on my Mac, but watching it on an external monitor that is directly connected to my Mac (i.e. no RealVNC (http://www.realvnc.com/) involved), and it's all working fine.

Puzzling...!?

Uwe
16th July 2015, 06:26
Is the initial problem - without the slower QwtPlotDirectPainter::FullRepaint workaround - also related to VNC ?

Uwe

agarny
16th July 2015, 08:44
Just to make sure that we are on the same page: my initial problem was with my whole plotting area becoming black when asking the direct painter to draw some points, and this was when running and watching my application on my MacBook Pro (i.e. no VNC involved). It might also happen with VNC, I cannot recall (I only ever use VNC with my MacBook Pro during weekends, if at all). If I have time this weekend, I will try various scenarios with and without VNC, this with my application and/or the oscilloscope example.

PS: in my case, to have QwtPlotDirectPainter::FullRepaint set to true doesn't slow down the rendering of points, but it certainly prevents my whole plotting area (and not only the bits where the direct painter draws some points) from becoming completely black.