Hi all,

In my MDI sub-window GUI I have two tabs: in one tab is a single large QGLWidget derived class, and in the other four QGLWidgets separated by splitters. They each have their own OpenGL contexts (for the actual painting), share another across all 5 (for geometry data), and share one application-wide (for shaders).

When drawing in the single viewport tab, it's very fast as expected; but when drawing in the quad view (each viewport is updated from a timer in creation order), the rendering speed plummets and gets worse with each viewport as the list is iterated through.

I began to profile and narrowed down the search to a Qt call that was taking so much longer in quad view than single view:

Qt Code:
  1. QPainter::end();
To copy to clipboard, switch view to plain text mode 
So when only the large single viewport is visible, I get QPainter::end() timings (in microseconds) like this:

Qt Code:
  1. Total time(us): 981
  2. Number of calls: 32
  3. Average call time(us): 30.656250
To copy to clipboard, switch view to plain text mode 
Quite reasonable. But when I switch to the quad view:

Qt Code:
  1. Viewport 1:
  2. Total time(us): 196023
  3. Number of calls: 32
  4. Average call time(us): 6125.718750
  5.  
  6. Viewport 2:
  7. Total time(us): 509769
  8. Number of calls: 32
  9. Average call time(us): 15930.281250
  10.  
  11. Viewport 3:
  12. Total time(us): 518504
  13. Number of calls: 32
  14. Average call time(us): 16203.250000
  15.  
  16. Viewport 4:
  17. Total time(us): 518226
  18. Number of calls: 32
  19. Average call time(us): 16194.562500
To copy to clipboard, switch view to plain text mode 
Vastly longer for what is supposed to be the same amount of work. Even stranger, is that it increases 200x(!), and then 2.5x for the next viewport before stabilising. If I run the tests for longer they give almost exactly the same readings - it doesn't increase any further.

The QPainter code in question is simply:

Qt Code:
  1. p.begin( this );
  2. p.beginNativePainting();
  3. glUseProgram( program_ );
  4.  
  5. glActiveTexture( GL_TEXTURE0 );
  6. glBindTexture( GL_TEXTURE_2D, buffer2d_->texture() );
  7. glActiveTexture( GL_TEXTURE1 );
  8. glBindTexture( GL_TEXTURE_2D, buffer3d_->texture() );
  9.  
  10. surfaceBuf_.bind();
  11. glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
  12. surfaceBuf_.unbind();
  13.  
  14. p.endNativePainting();
  15. p.end();
To copy to clipboard, switch view to plain text mode 
I browsed through the source code of the QPainter::end() and QOpenGLPaintEngine::end(), but it just seems to be state reversion and making sure the draw queue has been flushed. Considering I don't set any state requests, or do any drawing through Qt (all my calls are raw OpenGL) - it shouldn't have anything to do.

Why does the time increase even though the QPainter instance is created on the stack, and each viewport is doing the same amount of work?