PDA

View Full Version : QGLWidget + QEventDispatcherGlib::processEvents performance problem!



firas
27th March 2008, 22:09
greetings trollers,
Abstract
I have problem with QGLWidget and its Event loop or related (QEventDispatcherGlib::processEvents).
Introduction
I am sub-classing QGLWidget (class ImgFrame) and use that class (ImgFrame) to paint a QImage. The problem is: although I use separate thread object for manipulating a temporary image prior to copying it to the image of ImgFrame, the main thread uses a lot of CPU time for dispatching internal events not related to my code.
As a proof of this issue I sub-classed ImgFrame from QWidget instead and the processing speed became 50 folds faster.
Why Use QGLWidget?
Well, Intend to use this application mainly for real-time multi-threaded video processing and when painting in 30 frames per sec, drawing on QGLWidget has better performane than QWidget (see the 2dpainting example that comes with QT4.3)
Attachments
I attached the source code (Kdevelop project) and Valgrind performance analysis snapshot for further clearance.
thank you,
firas

spud
28th March 2008, 02:00
I don' see that your problem has anything to do with QGLWidget. I am testing on Windows, though so there could be some differences.

I guess you are wondering why the grayscale conversion takes forever.
Firstly don't use pixel() and setPixel() they are really inefficient!
Secondly, don't post more events than you need! That way it's no wonder that the event loop gets busy.

Just as a test try the following:


if(y%100==0)
QCoreApplication::postEvent(anaPen,new IplikEvent(4,mesajStr.setNum((100*y)/height)) );
QRgb* rgbLine = (QRgb*)crntImg->scanLine(y);
QRgb* grayLine = (QRgb*)sonucImg->scanLine(y);
for (uint x=0 ; x<width; ++x)
{
QRgb rgb = *rgbLine++;
uchar graylevelNTSC = (11 * qRed(rgb) + 16 * qGreen(rgb) + 5 * qBlue(rgb) )/32;
*grayLine++ = qRgb(graylevelNTSC,graylevelNTSC,graylevelNTSC);


And as a matter of coding style, I suggest you encapsulate your classes better. There is no way GriYapIpligi.cpp should have to include all the header files in your project.

firas
28th March 2008, 17:44
I don' see that your problem has anything to do with QGLWidget. I am testing on Windows, though so there could be some differences.

I guess you are wondering why the grayscale conversion takes forever.
Firstly don't use pixel() and setPixel() they are really inefficient!
Secondly, don't post more events than you need! That way it's no wonder that the event loop gets busy.

Thanx spud, maybe you where too quick to comment on this:


Check Callgrind output (profiling the application would be better though)
In class ImgFrame sub-class it from QWidget instead compile run and test again and let me know
I'm aware of the set/get pixel issue (although it is clearly not the problem)



And as a matter of coding style, I suggest you encapsulate your classes better. There is no way GriYapIpligi.cpp should have to include all the header files in your project.
I'm aware of this, it is not an issue.

firas
31st March 2008, 21:51
No reasonable explanation yet, Wysota maybe you have a say on this, I recall that you did help me once with a related issue.
thanx
firas

firas
7th May 2008, 00:01
Fixed, briefly instead of using qt based QGLWidget::paintEvent, I used directly OpenGL to draw my frames.
sample would be:



::initializeGL(){
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
}

::paintGL(){
glRasterPos2i(0,0);
glDrawPixels(pImg->width(), pImg->height(), GL_BGRA, GL_UNSIGNED_BYTE, pImg->bits());
glPixelZoom(1.0,-1.0);
glFlush();
}


For more interesting way google for "OpenGL programming guide (AKA OpenGL RedBook)"
salutations a tous qui m'aider!!
firas