Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QOpenGLWidget drawing performance drops as the widget number increases
QtWS25 Last Chance

QOpenGLWidget drawing performance drops as the widget number increases

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 4 Posters 1.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Sivan
    wrote on last edited by
    #1

    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)
      0_1528974357000_Screen Shot 2018-06-14 at 7.05.15 PM.png

    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.

    K 1 Reply Last reply
    0
    • S Sivan

      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)
        0_1528974357000_Screen Shot 2018-06-14 at 7.05.15 PM.png

      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.

      K Offline
      K Offline
      kenchan
      wrote on last edited by
      #2

      @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...

      1 Reply Last reply
      3
      • mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi
        as @kenchan wonders.
        Each QOpenGLWidget will take X timeunits to draw for gfx card.
        So the more there is, the lesser fps each will get.
        Just like running 2 games at same time.

        1 Reply Last reply
        1
        • S Offline
          S Offline
          Sivan
          wrote on last edited by
          #4

          Hi @kenchan and @mrjj,

          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.

          1 Reply Last reply
          0
          • O Offline
            O Offline
            ollarch
            wrote on last edited by
            #5

            @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.

            S 1 Reply Last reply
            0
            • O ollarch

              @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.

              S Offline
              S Offline
              Sivan
              wrote on last edited by
              #6

              @ollarch, that is a static const qpixmap. The pixnap would have been created only once and not for every paint event. By the way, there is a performance hit even if i just draw a fillrect.

              1 Reply Last reply
              0
              • O Offline
                O Offline
                ollarch
                wrote on last edited by
                #7

                And what about openGL context switching?

                S 1 Reply Last reply
                0
                • O ollarch

                  And what about openGL context switching?

                  S Offline
                  S Offline
                  Sivan
                  wrote on last edited by Sivan
                  #8

                  @ollarch I did set the attribute to shareContext, and verify that all the widgets are sharing context using QOpenGLContext::areSharing

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved