PDA

View Full Version : udateGL() with Nvidia&ATI



bahbah30
19th January 2011, 14:12
Hi,

my situation is following:

I write an app that have one QWidget. This widtget contains between 9 and 12 custom QGLWidget. Every custom QGLWidget get every 40 ms an image from a worker(which works in his one thread). I use PBO to copy imgaes in textur. And I use following connects:


connect(mCam, SIGNAL(renderedImage(const QImage &)), this, SLOT(updateTextur(const QImage &)));
QTimer *timer = new QTimer();
timer->start(40);
connect(timer,SIGNAL(timeout()),this,SLOT(updateGL ()),Qt::DirectConnection);


updateTextur is simple:


void OpenGLWidget::updateTextur(const QImage &image)
{
if(image.byteCount() > 0)
{
mImg = QImage(image);

}
}


Furthermore, I stop Time between painGL's invocation. And I get 47 ms with ATI and over 100 ms with NVidia!

Have sombody an idea why?

thanks!

wysota
19th January 2011, 17:47
Change byteCount() to isNull() and see if it changes anything. Apart from that - use a profiler to see where the bottle-neck of your application is.

bahbah30
20th January 2011, 12:14
Thank you for Answer!

I replaced byteCount() by isNull(), and I already profiled my app, But I can't find any bottle-neck.

But I saw some other problems:
My rozessor works with 50%, but if I put other window from other app over my app, than my app works with 20% and it stay on 20% if i do ohter window off.
If I put ohter window over half of my window, than I get better stop time (60 ms)

It is very strange! With ATI it works realy fine, but with NVIDIA come this Problems.

Somebody an idea?

thanks!

wysota
20th January 2011, 12:23
and I already profiled my app, But I can't find any bottle-neck.
Then it means you didn't profile you app. There is always a bottle-neck, it's nothing to be "found" really, it's the code path taking the most time.


But I saw some other problems:
My rozessor works with 50%,
You probably have two cores in your machine and the application uses only one. Do you use threads in your app?


but if I put other window from other app over my app, than my app works with 20%
Less to calculate/display.

and it stay on 20% if i do ohter window off.
I can't explain that.

If I put ohter window over half of my window, than I get better stop time (60 ms)
Less to calculate/display.

bahbah30
24th January 2011, 10:59
I used gprof to profile my app, but i found nothing, becouse my app is multithreded. And I use minGW. So I can't profile my app.

I have main.cpp and 3 other classes. Worker is in itsown thread. In main-tread is my MainWindows and my OpenGLWidget. OpenGLWidget will be shown between 9 and 12 times in MainWindow. If is stop time in painGL using QTime:


void OpenGLWidget::paintGL()
{
endTime1= t1.elapsed();//rest of the time
t.start();
paint();//openGL code
endTime = t.elapsed(); //within paintGL
t1.start();
}


endTime ist always 0. But the endTime1 is between 40 and 160 ms(with 12 widgets ) or 40 and 120 ms (with 9 widgets). But i do nothing in the rest of time. If I execute the same binary on ATI I get expected time (40 ms) Because :


QTimer *timer = new QTimer();
timer->start(40);
connect(timer,SIGNAL(timeout()),this,SLOT(updateGL ()),Qt::DirectConnection);


Use QT driver specific way to show an app?

thanks!

wysota
24th January 2011, 12:56
I used gprof to profile my app, but i found nothing, becouse my app is multithreded. And I use minGW. So I can't profile my app.
There is more than one profiling tool in the world.

So what do the threads do?

In general your application is eating up a lot of cpu power because you're repainting it constantly (even when there is nothing to repaint).

bahbah30
24th January 2011, 13:20
There is more than one profiling tool in the world..
Do you know one non commercial that works with minGW on windows (with multitreadinbg support)?


So what do the threads do?.
It encapsulates ffmpeg to decode Video and emits QImage as Signal.


In general your application is eating up a lot of cpu power because you're repainting it constantly (even when there is nothing to repaint)
I Know, but the question ist still, why it works fine on ATI and so bad on NVIDIA?

Thanks!

wysota
24th January 2011, 14:16
Do you know one non commercial that works with minGW on windows (with multitreadinbg support)?
I'm not that fond of Windows, sorry. You can run linux as a virtual machine and use Valgrind. That's the best profiling tool available. As for gprof, I know it can handle threads at least on Linux with a bit of tweaking. Moreover you can rem out the thread for now and emit bogus data - then you'll be able to use gprof directly.


It encapsulates ffmpeg to decode Video and emits QImage as Signal.
Can we see the code and the connect statement using the signal?



I Know, but the question ist still, why it works fine on ATI and so bad on NVIDIA?
You'd have to ask ATI and NVIDIA, their GL drivers are proprietary :) Nobody will be able to tell you the exact code paths used in both cases.

I suggest you start by getting rid of the timer and updating the widget when something really changes in it.

bahbah30
25th January 2011, 12:09
Hi,

now I have minimal exmaple of the problem as Attachment.5821

If I do following:


OpenGLWidget::OpenGLWidget( QWidget *parent):
QGLWidget(parent)
{
QTimer *mTimer = new QTimer();
mTimer->start(40);
connect(mTimer,SIGNAL(timeout()),this,SLOT(updateG L()));
}


I expect, that I get 40 as result of invoking this:


void OpenGLWidget::paintGL()
{
int a = t.elapsed();
t.start();
qDebug()<<"Time out of painGL: "<<a;
}


but it comes every thing, but not 40 ms.

thanks!

wysota
25th January 2011, 18:14
I would expect everything but 40ms.

bahbah30
25th January 2011, 18:49
I got it!

It was "vsync". I disabled vsync and it works how expected.

@wysota: Thank you that you tried to find a solution (dziękuję)