Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.12.7, 5.12.8, 5.15.0 RC2
-
None
-
macOS 10.14, macOS 10.15
-
-
01b2ea83aa0e8e1d624f6c25d78bb5184cd35483 (qt/qtbase/dev) 2fbcca719e02fa61aa69447a7d56f1a5c6371c36 (qt/qtbase/5.12) 8e5d6b422136dcca51f2c18fddcf28016f5ab99a (qt/qtbase/5.15)
Description
If OpenGL texture upload is used for QWidget backing store upload (e.g. because of /hidden/ QOpenGLWidget presence), performance is degraded on Mac if window width is not multiple of 16.
Details:
1) Opengl texture upload is used if texture backed widget is present somewhere (in my test app - it is at QStackedWidget hidden pane).
2) In that case, QPlatformGraphicsBufferHelper::bindSWToTexture is called.
3) It tests for
if (graphicsBuffer->bytesPerLine() != (size.width() * 4)) and the test fails in 15 cases out of 16, because backing store rows are aligned at 64 bytes.
If test fails extra QImage::convertToFormat is performed resulting in extra CPU usage and FPS drop.
4) Backing store alignment is performed in QIOSurfaceGraphicsBuffer::QIOSurfaceGraphicsBuffer by using
IOSurfaceAlignProperty(kIOSurfaceBytesPerRow, width * bytesPerElement)
So, if (window) with is not multiple of 16, alignment provided by QIOSurfaceGraphicsBuffer does not match alignment check performed in QPlatformGraphicsBufferHelper::bindSWToTexture
Attached sample app ( scrolltest2.zip ) illustrates the problem, it scrolls QListView programmatically. On my test system (i7-9700 @4.6 GHz, 4k monitor) it results in only 45fps and 100% CPU usage (about 30% of CPU time is used for QImage::convertFormat_helper). On 5K iMac Pro results are even worse because of lower single-core memory access speed and wider monitor so larger texture data to convert/transfer).
Qt 5.12.7 and 5.12.8 are heavily affected. On Qt 5.15RC2 QImage::convertToFormat uses all cores, so fps drop is not so dramatical.
Solution: use glPixelStore to not extra convert of backing store data, but upload it as is. Attached patch is proof of concept, but solves the issue for me qplatformgraphicsbufferhelper.patch
The patch restores fps rate to expected 60FPS and CPU usage is (slightly) below 100% with i7-9700. 5K ImacPro is worse, real fps is less than 60 w/ 100% CPU.