QOpenGLWidget drawing performance drops as the widget number increases
-
I have been working on a project where I need to have multiple QOpenGLWidgets. And I noticed that as the number of QOpenGLWidget increases, the performance (fps) drops. My target is to achieve 60fps.
To prove my point, I created a test app using QWidget as the parent in which I place a number of QOpenGLWidgets in a gridLayout. I used a timer with an interval of 16ms and connected it to a slot where I trigger an update to all the QOpenGLWidgets. Below is the related code for my QOpenWidget. I did nothing more than this in my QOpenGLWidget. I eliminated all other factors, and narrowed down to just drawing pixmaps, in this case, the same QPixmap in all the QOpenGLWidgets.
void MyOpenGLWidget::initializeGL() { QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); f->initializeOpenGLFunctions(); glClearColor(m_BgColor.redF(), m_BgColor.greenF(), m_BgColor.blueF(), 1); glEnable(GL_DEPTH_TEST); } void MyOpenGLWidget::paintGL() { glClear(GL_COLOR_BUFFER_BIT); QPainter painter(this); static const QPixmap p(":/OpenGLWidget/Pixmaps/MyTestPic.png"); painter.drawPixmap(10, 30, p); //fpsRendererHelperFunction(&painter); } void MyOpenGLWidget::resizeGL(int w, int h) { glViewport(0, 0, w, h); }
As I increase the number of QOpenGLWidget to 6, I started see to see the fps drops below 60. The more I increase from 6, the more it drops.
Here are the details of my machine and Qt:
- MacOS Sierra 10.12.2
- Qt 5.4.1
What I have found so far:
- I used Mac's time profiler to see what's happening underneath and the following caught my attention -
SCCompileShader
( i.e GPU driver forcing a recompile of the shader)
Googling about SCCompileShader - brought me to these 2 links which sort of give me some idea on what might be causing the performance drop ( I am still not sure if I am right about this)
- https://stackoverflow.com/questions/42238124/gldrawelements-on-osx-has-high-cpu-usage
- http://blog.jimmymakesstuff.com/2017/02/
And I am aware that Qt does have the code mentioned in the line
glActiveTexture(GL_TEXTURE0 + activeTextureUnit)
. However, removing that code from Qt for testing purpose didn't solve my issue (i.e I was still seeing the SCCompileShader call)I would like to understand on what is causing the
SCCompileShader
(if that is the cause of the performance drop) or what is the actual root cause for the performance drop. Why would the performance drop as I increase the number of QOpenGLWidget. Thanks in advance. -
I have been working on a project where I need to have multiple QOpenGLWidgets. And I noticed that as the number of QOpenGLWidget increases, the performance (fps) drops. My target is to achieve 60fps.
To prove my point, I created a test app using QWidget as the parent in which I place a number of QOpenGLWidgets in a gridLayout. I used a timer with an interval of 16ms and connected it to a slot where I trigger an update to all the QOpenGLWidgets. Below is the related code for my QOpenWidget. I did nothing more than this in my QOpenGLWidget. I eliminated all other factors, and narrowed down to just drawing pixmaps, in this case, the same QPixmap in all the QOpenGLWidgets.
void MyOpenGLWidget::initializeGL() { QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); f->initializeOpenGLFunctions(); glClearColor(m_BgColor.redF(), m_BgColor.greenF(), m_BgColor.blueF(), 1); glEnable(GL_DEPTH_TEST); } void MyOpenGLWidget::paintGL() { glClear(GL_COLOR_BUFFER_BIT); QPainter painter(this); static const QPixmap p(":/OpenGLWidget/Pixmaps/MyTestPic.png"); painter.drawPixmap(10, 30, p); //fpsRendererHelperFunction(&painter); } void MyOpenGLWidget::resizeGL(int w, int h) { glViewport(0, 0, w, h); }
As I increase the number of QOpenGLWidget to 6, I started see to see the fps drops below 60. The more I increase from 6, the more it drops.
Here are the details of my machine and Qt:
- MacOS Sierra 10.12.2
- Qt 5.4.1
What I have found so far:
- I used Mac's time profiler to see what's happening underneath and the following caught my attention -
SCCompileShader
( i.e GPU driver forcing a recompile of the shader)
Googling about SCCompileShader - brought me to these 2 links which sort of give me some idea on what might be causing the performance drop ( I am still not sure if I am right about this)
- https://stackoverflow.com/questions/42238124/gldrawelements-on-osx-has-high-cpu-usage
- http://blog.jimmymakesstuff.com/2017/02/
And I am aware that Qt does have the code mentioned in the line
glActiveTexture(GL_TEXTURE0 + activeTextureUnit)
. However, removing that code from Qt for testing purpose didn't solve my issue (i.e I was still seeing the SCCompileShader call)I would like to understand on what is causing the
SCCompileShader
(if that is the cause of the performance drop) or what is the actual root cause for the performance drop. Why would the performance drop as I increase the number of QOpenGLWidget. Thanks in advance.@Sivan
Sorry for asking, but I am interested to know why you think there should not be a performance drop of some sort when you add more QOpenGLWidget?
I would have thought that more widgets means more overhead and more work for your GPU so you would see some kind of performance hit, would you not?
Or is it more a question of you seeing more of a performance drop than you expected considering the work being done?
Just curious... -
Yes, I would like to think that there is an overhead. But what exact overhead are we talking about? And what is causing this overhead? Is it the QPainter?
Because, rendering on QOpenGLWidget using pure opengl command (just some badic primitive) does not drop the performance as the widget number increases.
-
@Sivan said in QOpenGLWidget drawing performance drops as the widget number increases:
static const QPixmap p(":/OpenGLWidget/Pixmaps/MyTestPic.png");
Could this cause the overhead? Every painting event is loading the image from disk. Try using a member image variable that have to be readed into constructor.
-
@Sivan said in QOpenGLWidget drawing performance drops as the widget number increases:
static const QPixmap p(":/OpenGLWidget/Pixmaps/MyTestPic.png");
Could this cause the overhead? Every painting event is loading the image from disk. Try using a member image variable that have to be readed into constructor.