Re: [PyQt] QGraphicsView very slow under Linux and Mac OS X

2013-07-18 Thread Clemens Brunner
Hi!

I investigated the problem a bit more, and it seems like it occurs only when 
I'm running KDE -- in Gnome, everything works as expected (the difference is 
1). Since it is now working on both Windows, Mac OS X, and non-KDE systems, it 
is probably related to KDE (maybe the window manager). Funny though, since KDE 
is based on Qt :-).

So if anyone running KDE wants to confirm the problem, I've attached the test 
program again.

Concerning the C++ version, the problem is also there on KDE, only you don't 
see it when just looking at the timer intervals (because they're always 25ms 
irrespective of the window size). However, the exposedRect on KDE is still 
wrong, so I assume that the C++ is just a lot faster so that performance is not 
(yet) affected in my example.

Clemens

import sys
from PyQt4 import QtGui, QtCore

import random
import math

class SignalItem(QtGui.QGraphicsItem):
def __init__(self, nr):
super(SignalItem, self).__init__()
self.setFlags(QtGui.QGraphicsItem.ItemUsesExtendedStyleOption)

self.nr = nr
self.fr = random.randint(3, 50)
self.bg = QtGui.QColor(random.randint(200,255),random.randint(200,255),random.randint(200,255))

def boundingRect(self):
return QtCore.QRectF(0, self.nr*50, 1, 50)

def paint(self, painter, option, widget):
painter.fillRect(option.exposedRect, self.bg)
self.prevY = math.sin((int(option.exposedRect.left()) - 1)/float(self.fr))*10 + 25 + self.nr*50
print(int(option.exposedRect.right()) - int(option.exposedRect.left()))
for x in range(int(option.exposedRect.left()), int(option.exposedRect.right())):
y = math.sin(x/float(self.fr))*10 + 25 + self.nr*50 
painter.drawLine(x-1, self.prevY, x, y)
self.prevY = y


class Dummy(QtCore.QObject):
def __init__(self):
super(Dummy, self).__init__()
self.scene = QtGui.QGraphicsScene()

for i in range(40):
item = SignalItem(i)
self.scene.addItem(item)

self.view = QtGui.QGraphicsView(self.scene)
self.view.show()

self.startTimer(25)
self.x = 0
self.lastTimerEvent = None

def timerEvent(self,event):
self.x += 1
self.view.horizontalScrollBar().setValue(self.x)
#currentTime = QtCore.QTime.currentTime()
#if self.lastTimerEvent:
#print self.lastTimerEvent.msecsTo(currentTime)
#self.lastTimerEvent = currentTime


if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
d = Dummy()
sys.exit(app.exec_())


On 04/05/2013 08:33 PM, Clemens Brunner wrote:
> Hi!
> 
> I think I found the problem: 
> https://bugreports.qt-project.org/browse/QTBUG-13573
> 
> The exposedRect returns the whole window width on Linux and Mac OS X, whereas 
> it correctly returns only the area that needs to be updated on Windows.
> 
> To illustrate this, just add the following line to my example code within the 
> paint() function just before the for loop:
> 
> print int(option.exposedRect.right()) - int(option.exposedRect.left())
> 
> On Windows, this is always 1, as expected. On Linux, this corresponds to the 
> window width.
> 
> This bug explains why it is so damn slow. However, it doesn't seem to occur 
> on all Linux platforms, since you guys get timer intervals as expected. Maybe 
> you want to check the output of the print statement above, but I assume it is 
> 1 on your platform. Which leads me to the question: how can we fix this bug? 
> Or is there at least a workaround?
> 
> I suspect that it might have something to do with the Intel graphics chip, 
> which I have in both my Linux and Mac machine.
> 
> [Update:] I just tested the behavior on my Mac again: in the first second, I 
> get the whole width for the exposedRect and large timer intervals (and 
> therefore slow performance). However, after about a second, I get the correct 
> value of 1, because Mac OS X switches from the Intel onboard chip to the 
> nVidia graphics chip. This is just a speculation, because disabling graphics 
> switching (which should permanently enable the nVidia chip) yields the same 
> behavior. Strangely though, it does work on my Mac now after this initial 
> second (maybe some updated got installed that fixed the problem?).
> 
> Any more ideas?
> 
> Clemens
> 
> 
> 
> On Apr 4, 2013, at 17:15 , Clemens Brunner  wrote:
> 
>> On 04/03/2013 06:46 PM, Hans-Peter Jansen wrote:
>> 
>>> Which graphic driver do you use? (that doesn't tell us much, since the C++
>>> version behave with the same driver, just for the record..)
>> 
>> xf86-video-intel 2.21.5-1
>> intel-dri 9.1.1-1
>> 
>>> Might be worth to compare the C++ version (that you should publish here¹)
>>> and the Python versions with perf. Of course, they differ...
>> 
>> Attached.
>> 
>>> python versions, perf running for about 10 sec.
>>> 
>>> QT_GRAPHICSSYSTEM=raster perf record -f python graphicsviewtest.py
>>> 

Re: [PyQt] QGraphicsView very slow under Linux and Mac OS X

2013-04-05 Thread Clemens Brunner
Hi!

I think I found the problem: 
https://bugreports.qt-project.org/browse/QTBUG-13573

The exposedRect returns the whole window width on Linux and Mac OS X, whereas 
it correctly returns only the area that needs to be updated on Windows.

To illustrate this, just add the following line to my example code within the 
paint() function just before the for loop:

print int(option.exposedRect.right()) - int(option.exposedRect.left())

On Windows, this is always 1, as expected. On Linux, this corresponds to the 
window width.

This bug explains why it is so damn slow. However, it doesn't seem to occur on 
all Linux platforms, since you guys get timer intervals as expected. Maybe you 
want to check the output of the print statement above, but I assume it is 1 on 
your platform. Which leads me to the question: how can we fix this bug? Or is 
there at least a workaround?

I suspect that it might have something to do with the Intel graphics chip, 
which I have in both my Linux and Mac machine.

[Update:] I just tested the behavior on my Mac again: in the first second, I 
get the whole width for the exposedRect and large timer intervals (and 
therefore slow performance). However, after about a second, I get the correct 
value of 1, because Mac OS X switches from the Intel onboard chip to the nVidia 
graphics chip. This is just a speculation, because disabling graphics switching 
(which should permanently enable the nVidia chip) yields the same behavior. 
Strangely though, it does work on my Mac now after this initial second (maybe 
some updated got installed that fixed the problem?).

Any more ideas?

Clemens



On Apr 4, 2013, at 17:15 , Clemens Brunner  wrote:

> On 04/03/2013 06:46 PM, Hans-Peter Jansen wrote:
> 
>> Which graphic driver do you use? (that doesn't tell us much, since the C++
>> version behave with the same driver, just for the record..)
> 
> xf86-video-intel 2.21.5-1
> intel-dri 9.1.1-1
> 
>> Might be worth to compare the C++ version (that you should publish here¹)
>> and the Python versions with perf. Of course, they differ...
> 
> Attached.
> 
>> python versions, perf running for about 10 sec.
>> 
>> QT_GRAPHICSSYSTEM=raster perf record -f python graphicsviewtest.py
>> 
>> [...]
>> 
>> 
>> QT_GRAPHICSSYSTEM=opengl perf record -f python graphicsviewtest.py
>> 
>> [...]
>> 
>> 
>> The former looks nice, it's a great example, why PyQt rocks. The hottest
>> areas are there, where they should be: down under, moving bits. Great.
>> 
>> But the latter looks strange indeed.
>> 
>> Phil, do you have any idea, why PyEval_EvalFrameEx is the top sucker in
>> this scenario? This looks, like in opengl mode, it is evaluating some
>> python expression in its hottest path (data type conversions or the like?).
> 
> My raster perf report doesn't look nice at all:
> 
> 14.30%  python2  libpython2.7.so.1.0   [.] PyEval_EvalFrameEx
>  9.39%  python2  libQtGui.so.4.8.4 [.] 0x001bf673
>  8.99%  python2  sip.so[.] 0xb086
>  6.10%  python2  libpython2.7.so.1.0   [.] lookdict_string
>  4.02%  python2  libpython2.7.so.1.0   [.] PyDict_GetItem
>  3.94%  python2  libpython2.7.so.1.0   [.] _PyType_Lookup
>  3.01%  python2  libm-2.17.so  [.] 0x000105e0
>  2.27%  python2  libm-2.17.so  [.] feraiseexcept
>  2.23%  python2  libpython2.7.so.1.0   [.] 
> _PyObject_GenericGetAttrWithDict
>  1.71%  python2  libpython2.7.so.1.0   [.] binary_op1
>  1.50%  python2  libpython2.7.so.1.0   [.] PyType_IsSubtype
>  1.40%  python2  libpython2.7.so.1.0   [.] PyErr_Restore
>  1.33%  python2  QtGui.so  [.] 0x0036120b
>  1.27%  python2  libpython2.7.so.1.0   [.] PyObject_Malloc
>  1.19%  python2  libc-2.17.so  [.] malloc
> 
> Same thing but even worse with opengl:
> 
> 15.49%  python2  i965_dri.so   [.] 0x0003ae99
>  6.08%  python2  libpython2.7.so.1.0   [.] PyEval_EvalFrameEx
>  5.96%  python2  libdrm_intel.so.1.0.0 [.] 0x7468
>  5.60%  python2  libQtOpenGL.so.4.8.4  [.] 0x00031262
>  4.96%  python2  sip.so[.] 0xb055
>  4.32%  python2  libdricore9.1.1.so.1.0.0  [.] 0x001ea2b4
>  2.76%  python2  libpython2.7.so.1.0   [.] lookdict_string
>  2.11%  python2  libpython2.7.so.1.0   [.] PyDict_GetItem
>  1.95%  python2  libpython2.7.so.1.0   [.] _PyType_Lookup
>  1.42%  python2  libm-2.17.so  [.] 0x000105c0
>  1.32%  python2  libc-2.17.so  [.] __memcmp_sse4_1
>  1.03%  python2  libc-2.17.so  [.] _int_malloc
>  1.01%  python2  libm-2.17.so  [.] feraiseexcept
>  0.93%  python2  libc-2.17.so  [.] __memcpy_ssse3_back
> 
> In both cases, PyEval_EvalFrameEx is at or near the top, and so are other 
> Python things.
> 
> For the sake of completeness, here's the perf output for the C++ version 
> (which runs perfectly):
> 
> 43.56%  graphicsvi

Re: [PyQt] QGraphicsView very slow under Linux and Mac OS X

2013-04-04 Thread Clemens Brunner

On 04/03/2013 06:46 PM, Hans-Peter Jansen wrote:


Which graphic driver do you use? (that doesn't tell us much, since the C++
version behave with the same driver, just for the record..)


xf86-video-intel 2.21.5-1
intel-dri 9.1.1-1


Might be worth to compare the C++ version (that you should publish here¹)
and the Python versions with perf. Of course, they differ...


Attached.


python versions, perf running for about 10 sec.

QT_GRAPHICSSYSTEM=raster perf record -f python graphicsviewtest.py

[...]


QT_GRAPHICSSYSTEM=opengl perf record -f python graphicsviewtest.py

[...]


The former looks nice, it's a great example, why PyQt rocks. The hottest
areas are there, where they should be: down under, moving bits. Great.

But the latter looks strange indeed.

Phil, do you have any idea, why PyEval_EvalFrameEx is the top sucker in
this scenario? This looks, like in opengl mode, it is evaluating some
python expression in its hottest path (data type conversions or the like?).


My raster perf report doesn't look nice at all:

 14.30%  python2  libpython2.7.so.1.0   [.] PyEval_EvalFrameEx
  9.39%  python2  libQtGui.so.4.8.4 [.] 0x001bf673
  8.99%  python2  sip.so[.] 0xb086
  6.10%  python2  libpython2.7.so.1.0   [.] lookdict_string
  4.02%  python2  libpython2.7.so.1.0   [.] PyDict_GetItem
  3.94%  python2  libpython2.7.so.1.0   [.] _PyType_Lookup
  3.01%  python2  libm-2.17.so  [.] 0x000105e0
  2.27%  python2  libm-2.17.so  [.] feraiseexcept
  2.23%  python2  libpython2.7.so.1.0   [.] _PyObject_GenericGetAttrWithDict
  1.71%  python2  libpython2.7.so.1.0   [.] binary_op1
  1.50%  python2  libpython2.7.so.1.0   [.] PyType_IsSubtype
  1.40%  python2  libpython2.7.so.1.0   [.] PyErr_Restore
  1.33%  python2  QtGui.so  [.] 0x0036120b
  1.27%  python2  libpython2.7.so.1.0   [.] PyObject_Malloc
  1.19%  python2  libc-2.17.so  [.] malloc

Same thing but even worse with opengl:

 15.49%  python2  i965_dri.so   [.] 0x0003ae99
  6.08%  python2  libpython2.7.so.1.0   [.] PyEval_EvalFrameEx
  5.96%  python2  libdrm_intel.so.1.0.0 [.] 0x7468
  5.60%  python2  libQtOpenGL.so.4.8.4  [.] 0x00031262
  4.96%  python2  sip.so[.] 0xb055
  4.32%  python2  libdricore9.1.1.so.1.0.0  [.] 0x001ea2b4
  2.76%  python2  libpython2.7.so.1.0   [.] lookdict_string
  2.11%  python2  libpython2.7.so.1.0   [.] PyDict_GetItem
  1.95%  python2  libpython2.7.so.1.0   [.] _PyType_Lookup
  1.42%  python2  libm-2.17.so  [.] 0x000105c0
  1.32%  python2  libc-2.17.so  [.] __memcmp_sse4_1
  1.03%  python2  libc-2.17.so  [.] _int_malloc
  1.01%  python2  libm-2.17.so  [.] feraiseexcept
  0.93%  python2  libc-2.17.so  [.] __memcpy_ssse3_back

In both cases, PyEval_EvalFrameEx is at or near the top, and so are other 
Python things.

For the sake of completeness, here's the perf output for the C++ version (which 
runs perfectly):

 43.56%  graphicsviewtes  libQtGui.so.4.8.4 [.] 0x001c0bb2  
 q
 20.58%  graphicsviewtes  libm-2.17.so  [.] feraiseexcept
 15.48%  graphicsviewtes  libm-2.17.so  [.] 0x00015622
  4.47%  graphicsviewtes  graphicsviewtest  [.] 
SignalItem::paint(QPainter*, QStyleOptionGraphicsItem
  3.09%  graphicsviewtes  libQtGui.so.4.8.4 [.] QPen::dashPattern() 
const
  1.17%  graphicsviewtes  libQtGui.so.4.8.4 [.] QTransform::map(QPointF 
const&) const
  0.77%  graphicsviewtes  libc-2.17.so  [.] free
  0.72%  graphicsviewtes  libQtGui.so.4.8.4 [.] 
QPainter::drawLines(QLine const*, int)
  0.46%  graphicsviewtes  libpthread-2.17.so[.] 
__pthread_mutex_unlock_usercnt
  0.45%  graphicsviewtes  libpthread-2.17.so[.] pthread_mutex_lock

I tested this program on openSUSE (in a VirtualBox), and in contrast to 
Vincent, it doesn't work for me there either (same behavior as in my native 
Arch Linux). BTW, I use KDE and not Gnome, but I doubt that this is relevant. 
Furthermore, I still have the same bad behavior on my Mac.

Clemens
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

class SignalItem : public QGraphicsItem
{
public:
SignalItem(int nr)
{
setFlags(QGraphicsItem::ItemUsesExtendedStyleOption);
nr_ = nr;
fr_ = 20;
bg_ = Qt::white;
}

QRectF boundingRect() const
{
return QRectF(0, nr_*50, 1, 50);
}

void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0)
{
painter->fillRect(option->exposedRect, bg_);
float prevY = sin((int(option->exposedRect.left()) - 1)/fr_)*10 + 25 + nr_*50;
for (int x = int(option->expo

Re: [PyQt] QGraphicsView very slow under Linux and Mac OS X

2013-04-04 Thread Clemens Brunner

On 04/03/2013 05:09 PM, Andreas Pakulat wrote:


As I said, with Qt4.8 I don't see this here on Linux at all, once the
window is at a certain size the timer fires every 25 ms again. This is
on a somewhat new system with Debians standard Qt/PyQt packages. So its
not necessarily a general problem with Linux/PyQt, but might be limited
to the systems you've used so far to reproduce this or a configuration
thing etc.


Strange. I tried it on my Arch Linux as well as on openSUSE (inside 
VirtualBox), and I never get 25ms... I do get 25ms on Windows inside 
VirtualBox though. Plus I do get 25ms on all platforms when I run the 
C++ version.



It could also be the fact that the various helpers inside your paint are
slower in Python on *nix for whatever reason. Did you try further
simplifying the paint function, for example simply painting 1 line
across the whole rect in multiple steps? Or try out a single step? That
way you'd be able to get rid of all the math which could affect the
result too.
[...]

I doubt there's much difference in the PyQt/PySide code between Windows
and *nix, after all the C API of CPython is the same on both platforms.
One difference though is the compiler being used for both - at least
usually it is a different one - and of course the platform itself. Does
a fixed-length sleep instead of the paint() function produce a different
result on Linux? Meaning, does it matter what exactly happens in paint
or that its just not a noop?


It does depend on how much I draw. If I only fill the backgrounds, I get 
25ms. However, if I get rid of all the math functions and just paint a 
constant line, the program gets slower when this line is visible:


def paint(self, painter, option, widget):
painter.fillRect(option.exposedRect, self.bg)
for x in range(int(option.exposedRect.left()), 
int(option.exposedRect.right())):

painter.drawLine(x-1, 20, x, 40)

I will talk about the output of perf in my reply to Hans-Peter's post.

Clemens
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] QGraphicsView very slow under Linux and Mac OS X

2013-04-03 Thread Hans-Peter Jansen
On Mittwoch, 3. April 2013 17:28:28 Clemens Brunner wrote:
> On 04/03/2013 04:23 PM, Hans-Peter Jansen wrote:
> > What you see is possibly related to the default Qt graphics engine:
> > 
> > when using:
> > QT_GRAPHICSSYSTEM=opengl python graphicsviewtest.py
> > 
> > the values are oscillating around 150 here. With "native" and "raster",
> > it's back to 25: openSUSE 12.2/x86_64, 2560x1600x32, nvidia proprietary
> > graphics,
> That's what I suspected initially. However, my graphics engine was set
> to native by default. I just tried all three engines:
> * native: around 100ms
> * raster: around 100ms
> * opengl: greater than 300ms
> 
> I tested it on Arch Linux x86_64, 1920x1080, python2 2.7.3-4, sip
> 4.14.5-1, qt4 4.8.4-16, python2-pyqt 4.10-1.

Which graphic driver do you use? (that doesn't tell us much, since the C++ 
version behave with the same driver, just for the record..)

> That's really weird... I will try to set up an openSUSE box in my
> VirtualBox to see if that works.

Might be worth to compare the C++ version (that you should publish here¹) 
and the Python versions with perf. Of course, they differ...

python versions, perf running for about 10 sec.

QT_GRAPHICSSYSTEM=raster perf record -f python graphicsviewtest.py 

 21,06%  python  libc-2.15.so [.] __memmove_ssse3_back
  3,34%  python  libc-2.15.so [.] __strcmp_sse42
  2,97%  python  libpython2.7.so.1.0  [.] PyEval_EvalFrameEx
  2,67%  python  libpython2.7.so.1.0  [.] lookdict_string
  2,65%  python  libQtGui.so.4.8.4[.] QWidget::qt_metacast(char const*)
  2,42%  python  libGL.so.304.64  [.] 0x000a01ed
  1,50%  python  libnvidia-tls.so.304.64  [.] 0x1c70
  1,27%  python  libpython2.7.so.1.0  [.] PyDict_GetItem
  1,12%  python  libpthread-2.15.so   [.] pthread_mutex_lock
  1,07%  python  sip.so   [.] parsePass1
  1,04%  python  libpthread-2.15.so   [.] __pthread_mutex_unlock_usercnt
  1,03%  python  libQtCore.so.4.8.4   [.] QObject::qt_metacast(char const*)
  1,00%  python  libpython2.7.so.1.0  [.] _init


QT_GRAPHICSSYSTEM=opengl perf record -f python graphicsviewtest.py

 10,12%  python  libpython2.7.so.1.0 [.] PyEval_EvalFrameEx
  4,94%  python  libpython2.7.so.1.0 [.] lookdict_string
  4,63%  python  libnvidia-glcore.so.304.64  [.] 0x013aed80
  3,53%  python  sip.so  [.] parsePass1
  3,26%  python  libpython2.7.so.1.0 [.] PyDict_GetItem
  2,68%  python  libpython2.7.so.1.0 [.] _PyType_Lookup
  1,91%  python  libm-2.15.so[.] __sin_sse2
  1,72%  python  libQtGui.so.4.8.4   [.] QBrush::~QBrush()
  1,69%  python  libQtOpenGL.so.4.8.4[.] 
QTriangulatingStroker::process(QVectorPath const&, QPen const&, QRectF
  1,51%  python  libpython2.7.so.1.0 [.] _init
  1,39%  python  libpython2.7.so.1.0 [.] binary_op1
  1,29%  python  libpython2.7.so.1.0 [.] 
_PyObject_GenericGetAttrWithDict
  1,27%  python  sip.so  [.] parsePass2
  1,21%  python  libGL.so.304.64 [.] 0x000a19c6
  1,16%  python  libQtOpenGL.so.4.8.4[.] 
QTriangulatingStroker::moveTo(double const*)
  1,15%  python  libpython2.7.so.1.0 [.] PyErr_Restore
  1,11%  python  libc-2.15.so[.] _int_free
  1,09%  python  libc-2.15.so[.] malloc
  1,08%  python  libQtGui.so.4.8.4   [.] QPainter::drawLines(QLine 
const*, int)
  1,00%  python  libQtOpenGL.so.4.8.4[.] 
QGL2PaintEngineExPrivate::updateMatrix()


The former looks nice, it's a great example, why PyQt rocks. The hottest
areas are there, where they should be: down under, moving bits. Great.

But the latter looks strange indeed. 

Phil, do you have any idea, why PyEval_EvalFrameEx is the top sucker in 
this scenario? This looks, like in opengl mode, it is evaluating some 
python expression in its hottest path (data type conversions or the like?). 
BTW: the opengl version crashes always on exit for me:

Program received signal SIGSEGV, Segmentation fault.
XQueryExtension (dpy=dpy@entry=0x0, name=name@entry=0x70a374b4 "GLX", 
major_opcode=major_opcode@entry=
0x7fffd104, first_event=first_event@entry=0x7fffd108, 
first_error=first_error@entry=0x7fffd10c)
at QuExt.c:57


#0  XQueryExtension (dpy=dpy@entry=0x0, name=name@entry=0x70a374b4 "GLX", 
major_opcode=major_opcode@entry=
0x7fffd104, first_event=first_event@entry=0x7fffd108, 
first_error=first_error@entry=0x7fffd10c)
at QuExt.c:57
rep = {type = 0 '\000', pad1 = 0 '\000', sequenceNumber = 0, length = 
0, present = 0 '\000', major_opcode = 
0 '\000', first_event = 0 '\000', first_error = 0 '\000', pad3 = 1, pad4 = 
0, pad5 = 0, pad6 = 4036989387, pad7 = 
32767}
req = 
#1  0x72813492 in XInitExtension (dpy=dpy@entry=0x0, 
name=name@entry=0x70a374b4 "GLX") at InitExt.c:47
codes = {

Re: [PyQt] QGraphicsView very slow under Linux and Mac OS X

2013-04-03 Thread Vincent Vande Vyvre
Le 03/04/13 17:28, Clemens Brunner a écrit :
> On 04/03/2013 04:23 PM, Hans-Peter Jansen wrote:
>
>> What you see is possibly related to the default Qt graphics engine:
>> when using:
>>
>> QT_GRAPHICSSYSTEM=opengl python graphicsviewtest.py
>>
>> the values are oscillating around 150 here. With "native" and
>> "raster", it's
>> back to 25: openSUSE 12.2/x86_64, 2560x1600x32, nvidia proprietary
>> graphics,
>
> That's what I suspected initially. However, my graphics engine was set
> to native by default. I just tried all three engines:
> * native: around 100ms
> * raster: around 100ms
> * opengl: greater than 300ms
>
> I tested it on Arch Linux x86_64, 1920x1080, python2 2.7.3-4, sip
> 4.14.5-1, qt4 4.8.4-16, python2-pyqt 4.10-1.
>
> That's really weird... I will try to set up an openSUSE box in my
> VirtualBox to see if that works.
>
> Clemens
> ___
> PyQt mailing listPyQt@riverbankcomputing.com
> http://www.riverbankcomputing.com/mailman/listinfo/pyqt
>
Tested on Ubuntu, after removed the unusued import QtOpenGL.

-
On a 32 bytes machine screen 1600x900
Python 2.6.5  on a 32 bytes machine
Qt 4.6.2
PyQt 4.7.2
 27 23 26 24 25 25 25 25 25 25 25 25 25 25 25 25 27 23 25 25 25 25
25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 26 24 26 24 26 24 26 24 26
24 26 24 26 24 25 26 24 25 25 25 25
-
On a 64 bytes machine screen 1600x900
Python 2.7.3
Qt 4.8.1
PyQt 4.9.1

 25 25 25 25 25 25 25 25 25 25 25 25 25 25 26 24 25 25 25 25 25 25
25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25
25 25 25 25 25 25 25 25 25 25

Python 3.2.3
Qt 4.8.1
PyQt 4.9.1

 24 25 26 25 25 24 26 25 25 24 26 25 25 25 25 25 25 24 26 25 25 24
26 25 25 24 26 25 25 25 25 25 25 25 25 25 25 25 25 25


All three test in full screen of course.
-- 
Vincent V.V.
Oqapy  . Qarte
 . PaQager 
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] QGraphicsView very slow under Linux and Mac OS X

2013-04-03 Thread Clemens Brunner

On 04/03/2013 04:23 PM, Hans-Peter Jansen wrote:


What you see is possibly related to the default Qt graphics engine:
when using:

QT_GRAPHICSSYSTEM=opengl python graphicsviewtest.py

the values are oscillating around 150 here. With "native" and "raster", it's
back to 25: openSUSE 12.2/x86_64, 2560x1600x32, nvidia proprietary graphics,


That's what I suspected initially. However, my graphics engine was set 
to native by default. I just tried all three engines:

* native: around 100ms
* raster: around 100ms
* opengl: greater than 300ms

I tested it on Arch Linux x86_64, 1920x1080, python2 2.7.3-4, sip 
4.14.5-1, qt4 4.8.4-16, python2-pyqt 4.10-1.


That's really weird... I will try to set up an openSUSE box in my 
VirtualBox to see if that works.


Clemens
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] QGraphicsView very slow under Linux and Mac OS X

2013-04-03 Thread Andreas Pakulat
Hi


On Wed, Apr 3, 2013 at 3:50 PM, Clemens Brunner
wrote:

> On 04/03/2013 03:24 PM, Andreas Pakulat wrote:
>
 That being said, here with Qt4.8 even a full-screen window will not
>> cause a significant slowdown, except during the resize phase.  Once the
>> resize is done the timer fires every 25 ms again. So I guess the
>> calculation inside the paint function simply take some time and once the
>> widget doesn't resize anymore the paint function is not called anymore.
>>
>
> OK, but (1) I was not referring to the resize phase, and (2) this only
> works well on Windows. On Mac OS X and Linux, the timer depends on the size
> of the window being updated -- for a full screen window, the timer fires
> every 100ms (not during the resize) because QGraphicsView cannot handle the
> computations within a time frame less than 100ms anymore.


As I said, with Qt4.8 I don't see this here on Linux at all, once the
window is at a certain size the timer fires every 25 ms again. This is on a
somewhat new system with Debians standard Qt/PyQt packages. So its not
necessarily a general problem with Linux/PyQt, but might be limited to the
systems you've used so far to reproduce this or a configuration thing etc.


>  If you need high precision timers then you'll need to write
>> platform-specific code. QTimer is not meant for that.
>>
>> Why this works better on Windows with Py(Qt/Side) can have many reasons,
>> the whole graphicsstack is different there, the QTimer might be
>> implemented differently there. Maybe windows delays the painting during
>> resize somewhat more so that there are less repaint-events given to Qt
>> or maybe the functions used in your paint() are more optimized on Windows.
>>
>
> Well, the fact that it does work equally well on all three platforms when
> I use Qt directly from a C++ program indicates that this is an issue with
> the Python wrapper


It could also be the fact that the various helpers inside your paint are
slower in Python on *nix for whatever reason. Did you try further
simplifying the paint function, for example simply painting 1 line across
the whole rect in multiple steps? Or try out a single step? That way you'd
be able to get rid of all the math which could affect the result too.


> , and not a different implementation within the Qt framework. Furthermore,
> since PyQt and PySide produce a Python wrapper that does work just like its
> C++ counterpart under Windows makes me think that it must be an
> implementation detail of PyQt/PySide that could probably be fixed.


I doubt there's much difference in the PyQt/PySide code between Windows and
*nix, after all the C API of CPython is the same on both platforms. One
difference though is the compiler being used for both - at least usually it
is a different one - and of course the platform itself. Does a fixed-length
sleep instead of the paint() function produce a different result on Linux?
Meaning, does it matter what exactly happens in paint or that its just not
a noop?

Andreas
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt

Re: [PyQt] QGraphicsView very slow under Linux and Mac OS X

2013-04-03 Thread Hans-Peter Jansen
On Mittwoch, 3. April 2013 15:50:46 Clemens Brunner wrote:
> On 04/03/2013 03:24 PM, Andreas Pakulat wrote:
> > first of all, QTimer gives you no guarantee that it'll fire exactly
> > after the given amount of time. In particular not with such small
> > timeouts and when having non-trivial paint functions like yours. QTimer
> > is bound to the event loop, hence cannot fire if the loop is being
> > blocked by something. If you simplify the paint function the effect will
> > be much less dramatic.
> 
> Yes, I know that QTimer is not a high-precision timer. This is also not
> a problem in my example, since I can live with a bit of jitter.
> 
> > That being said, here with Qt4.8 even a full-screen window will not
> > cause a significant slowdown, except during the resize phase.  Once the
> > resize is done the timer fires every 25 ms again. So I guess the
> > calculation inside the paint function simply take some time and once the
> > widget doesn't resize anymore the paint function is not called anymore.
> 
> OK, but (1) I was not referring to the resize phase, and (2) this only
> works well on Windows. On Mac OS X and Linux, the timer depends on the
> size of the window being updated -- for a full screen window, the timer
> fires every 100ms (not during the resize) because QGraphicsView cannot
> handle the computations within a time frame less than 100ms anymore.
> 
> > If you need high precision timers then you'll need to write
> > platform-specific code. QTimer is not meant for that.
> > 
> > Why this works better on Windows with Py(Qt/Side) can have many reasons,
> > the whole graphicsstack is different there, the QTimer might be
> > implemented differently there. Maybe windows delays the painting during
> > resize somewhat more so that there are less repaint-events given to Qt
> > or maybe the functions used in your paint() are more optimized on Windows.
> 
> Well, the fact that it does work equally well on all three platforms
> when I use Qt directly from a C++ program indicates that this is an
> issue with the Python wrapper, and not a different implementation within
> the Qt framework. Furthermore, since PyQt and PySide produce a Python
> wrapper that does work just like its C++ counterpart under Windows makes
> me think that it must be an implementation detail of PyQt/PySide that
> could probably be fixed.

What you see is possibly related to the default Qt graphics engine:
when using: 

QT_GRAPHICSSYSTEM=opengl python graphicsviewtest.py

the values are oscillating around 150 here. With "native" and "raster", it's 
back to 25: openSUSE 12.2/x86_64, 2560x1600x32, nvidia proprietary graphics,

python: 2.7.3
sip: 4.14.5-snapshot-054f1676c300
qt4: 4.8.4
pyqt4: snapshot-4.10.1-3ade65901e3e

Cheers,
Pete
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] QGraphicsView very slow under Linux and Mac OS X

2013-04-03 Thread Clemens Brunner

On 04/03/2013 03:24 PM, Andreas Pakulat wrote:


first of all, QTimer gives you no guarantee that it'll fire exactly
after the given amount of time. In particular not with such small
timeouts and when having non-trivial paint functions like yours. QTimer
is bound to the event loop, hence cannot fire if the loop is being
blocked by something. If you simplify the paint function the effect will
be much less dramatic.


Yes, I know that QTimer is not a high-precision timer. This is also not 
a problem in my example, since I can live with a bit of jitter.



That being said, here with Qt4.8 even a full-screen window will not
cause a significant slowdown, except during the resize phase.  Once the
resize is done the timer fires every 25 ms again. So I guess the
calculation inside the paint function simply take some time and once the
widget doesn't resize anymore the paint function is not called anymore.


OK, but (1) I was not referring to the resize phase, and (2) this only 
works well on Windows. On Mac OS X and Linux, the timer depends on the 
size of the window being updated -- for a full screen window, the timer 
fires every 100ms (not during the resize) because QGraphicsView cannot 
handle the computations within a time frame less than 100ms anymore.



If you need high precision timers then you'll need to write
platform-specific code. QTimer is not meant for that.

Why this works better on Windows with Py(Qt/Side) can have many reasons,
the whole graphicsstack is different there, the QTimer might be
implemented differently there. Maybe windows delays the painting during
resize somewhat more so that there are less repaint-events given to Qt
or maybe the functions used in your paint() are more optimized on Windows.


Well, the fact that it does work equally well on all three platforms 
when I use Qt directly from a C++ program indicates that this is an 
issue with the Python wrapper, and not a different implementation within 
the Qt framework. Furthermore, since PyQt and PySide produce a Python 
wrapper that does work just like its C++ counterpart under Windows makes 
me think that it must be an implementation detail of PyQt/PySide that 
could probably be fixed.


Clemens
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] QGraphicsView very slow under Linux and Mac OS X

2013-04-03 Thread Andreas Pakulat
Hi,

On Wed, Apr 3, 2013 at 2:15 PM, Clemens Brunner
wrote:

> Hi,
>
> I've also posted this question as a bug report at qt-project.org (
> https://bugreports.qt-project.org/browse/PYSIDE-151), but this is also a
> PyQt issue.
>
> QGraphicsView is apparently very slow under Linux and Mac OS X. I've
> attached an example program (runs with PySide or PyQt). The signals should
> be updated every 25ms; the actual timer intervals are displayed on the
> console. Now under Linux and Mac OS X, the graphics get slower with
> increasing window size. In full screen, the timer intervals are around
> 100ms instead of 25ms on my machines.
>
> This problem does not exist under Windows. Here, the intervals are not
> affected by window size, and the intervals stay at the given values.
> Interestingly, the program runs perfectly fast even in a Windows inside a
> VM.
>
> Furthermore, this problem is PySide (or PyQt) specific, because this
> behavior does not occur when I use Qt from C+. In C+, the program works as
> expected on all three platforms.
>

first of all, QTimer gives you no guarantee that it'll fire exactly after
the given amount of time. In particular not with such small timeouts and
when having non-trivial paint functions like yours. QTimer is bound to the
event loop, hence cannot fire if the loop is being blocked by something. If
you simplify the paint function the effect will be much less dramatic.

That being said, here with Qt4.8 even a full-screen window will not cause a
significant slowdown, except during the resize phase.  Once the resize is
done the timer fires every 25 ms again. So I guess the calculation inside
the paint function simply take some time and once the widget doesn't resize
anymore the paint function is not called anymore.

If you need high precision timers then you'll need to write
platform-specific code. QTimer is not meant for that.

Why this works better on Windows with Py(Qt/Side) can have many reasons,
the whole graphicsstack is different there, the QTimer might be implemented
differently there. Maybe windows delays the painting during resize somewhat
more so that there are less repaint-events given to Qt or maybe the
functions used in your paint() are more optimized on Windows.

Andreas
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt

[PyQt] QGraphicsView very slow under Linux and Mac OS X

2013-04-03 Thread Clemens Brunner
Hi,

I've also posted this question as a bug report at qt-project.org 
(https://bugreports.qt-project.org/browse/PYSIDE-151), but this is also a PyQt 
issue.

QGraphicsView is apparently very slow under Linux and Mac OS X. I've attached 
an example program (runs with PySide or PyQt). The signals should be updated 
every 25ms; the actual timer intervals are displayed on the console. Now under 
Linux and Mac OS X, the graphics get slower with increasing window size. In 
full screen, the timer intervals are around 100ms instead of 25ms on my 
machines.

This problem does not exist under Windows. Here, the intervals are not affected 
by window size, and the intervals stay at the given values. Interestingly, the 
program runs perfectly fast even in a Windows inside a VM.

Furthermore, this problem is PySide (or PyQt) specific, because this behavior 
does not occur when I use Qt from C+. In C+, the program works as expected on 
all three platforms.

Thanks,
Clemens

import sys
from PyQt4 import QtGui, QtCore, QtOpenGL

import random
import math

class SignalItem(QtGui.QGraphicsItem):
def __init__(self, nr):
super(SignalItem, self).__init__()
self.setFlags(QtGui.QGraphicsItem.ItemUsesExtendedStyleOption)

self.nr = nr
self.fr = random.randint(3, 50)
self.bg = QtGui.QColor(random.randint(200,255),random.randint(200,255),random.randint(200,255))

def boundingRect(self):
return QtCore.QRectF(0, self.nr*50, 1, 50)

def paint(self, painter, option, widget):
painter.fillRect(option.exposedRect, self.bg)
self.prevY = math.sin((int(option.exposedRect.left()) - 1)/float(self.fr))*10 + 25 + self.nr*50
for x in range(int(option.exposedRect.left()), int(option.exposedRect.right())):
y = math.sin(x/float(self.fr))*10 + 25 + self.nr*50 
painter.drawLine(x-1, self.prevY, x, y)
self.prevY = y


class Dummy(QtCore.QObject):
def __init__(self):
super(Dummy, self).__init__()
self.scene = QtGui.QGraphicsScene()

for i in range(40):
item = SignalItem(i)
self.scene.addItem(item)

self.view = QtGui.QGraphicsView(self.scene)
self.view.show()

self.startTimer(25)
self.x = 0
self.lastTimerEvent = None

def timerEvent(self,event):
self.x += 1
self.view.horizontalScrollBar().setValue(self.x)
currentTime = QtCore.QTime.currentTime()
if self.lastTimerEvent:
print self.lastTimerEvent.msecsTo(currentTime)
self.lastTimerEvent = currentTime


if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
d = Dummy()
sys.exit(app.exec_())
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt