Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-62392

OpenGL shaders cached by qsgbatchrenderer's ShaderManager are not freed until application is closed

    XMLWordPrintable

Details

    Description

      When a QML component containing a graphical effect (e.g. FastBlur) is created, Qt creates instances of QOpenGLShaderProgram and adds them to an internal cache. Unfortunately, these instances are not freed when the corresponding QML items are destructed and there seems to be no way to manually free no longer used shaders.

      As the result, the memory consumption grows when new QML components are loaded and unloaded (using Loader), causing significant overhead. In our application, after loading and unloading of just one screen, the heap size reported by TCMalloc changes as follows:

      • before the screen was loaded: 105,7 MiB in use by application
      • screen was loaded: 145,5 MiB in use by application
      • after screen was unloaded: 118,1 MiB in use by application
        As you can see, 31% of 39.8 MB are still in use. I have called trimComponentCache and cleared QQuickImage caches before measuring the memory consumption.

      Valgrind reports that about 3 MB of memory still in use was allocated by QOpenGLShaderProgram::link. Excerpt from valgrind log (I cannot publicly post the full log):

      ==30519== 2,560 (+2,560) bytes in 4 (+4) blocks are possibly lost in loss record 101,066 of 103,292
      ==30519==    at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
      ==30519==    by 0x1BC8B0C1: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BD766C7: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BB03815: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x6337844: ??? (in /home/abusenius/qt/5.6/gcc_64/lib/libQt5Gui.so.5.6.2)
      ==30519==    by 0x6338122: QOpenGLShader::QOpenGLShader(QFlags<QOpenGLShader::ShaderTypeBit>, QObject*) (in /home/abusenius/qt/5.6/gcc_64/lib/libQt5Gui.so.5.6.2)
      ==30519==    by 0x633C7C2: QOpenGLShaderProgram::addShaderFromSourceCode(QFlags<QOpenGLShader::ShaderTypeBit>, char const*) (in /home/abusenius/qt/5.6/gcc_64/lib/libQt5Gui.so.5.6.2)
      ==30519==    by 0x5AD0501: QQuickCustomMaterialShader::compile() (qquickshadereffectnode.cpp:256)
      ==30519==    by 0x59259CD: QSGRenderContext::compile(QSGMaterialShader*, QSGMaterial*, char const*, char const*) (qsgcontext.cpp:825)
      ==30519==    by 0x58E0BCD: QSGBatchRenderer::ShaderManager::prepareMaterialNoRewrite(QSGMaterial*) (qsgbatchrenderer.cpp:185)
      ==30519==    by 0x58EC1A9: QSGBatchRenderer::Renderer::renderUnmergedBatch(QSGBatchRenderer::Batch const*) (qsgbatchrenderer.cpp:2350)
      ==30519==    by 0x58ED2EF: QSGBatchRenderer::Renderer::renderBatches() (qsgbatchrenderer.cpp:2511)
      
      ==30519== 19,864 (+19,864) bytes in 191 (+191) blocks are possibly lost in loss record 102,792 of 103,292
      ==30519==    at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
      ==30519==    by 0x1BC8B0C1: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BC6CE55: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BC6C7D6: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BB038AD: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x63378E8: ??? (in /home/abusenius/qt/5.6/gcc_64/lib/libQt5Gui.so.5.6.2)
      ==30519==    by 0x633856C: QOpenGLShader::compileSourceCode(char const*) (in /home/abusenius/qt/5.6/gcc_64/lib/libQt5Gui.so.5.6.2)
      ==30519==    by 0x633C7D2: QOpenGLShaderProgram::addShaderFromSourceCode(QFlags<QOpenGLShader::ShaderTypeBit>, char const*) (in /home/abusenius/qt/5.6/gcc_64/lib/libQt5Gui.so.5.6.2)
      ==30519==    by 0x5AD0501: QQuickCustomMaterialShader::compile() (qquickshadereffectnode.cpp:256)
      ==30519==    by 0x59259CD: QSGRenderContext::compile(QSGMaterialShader*, QSGMaterial*, char const*, char const*) (qsgcontext.cpp:825)
      ==30519==    by 0x58E0BCD: QSGBatchRenderer::ShaderManager::prepareMaterialNoRewrite(QSGMaterial*) (qsgbatchrenderer.cpp:185)
      ==30519==    by 0x58EC1A9: QSGBatchRenderer::Renderer::renderUnmergedBatch(QSGBatchRenderer::Batch const*) (qsgbatchrenderer.cpp:2350)
      
      ==30519== 69,688 (+69,688) bytes in 281 (+281) blocks are still reachable in loss record 103,153 of 103,292
      ==30519==    at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
      ==30519==    by 0x1BC8B0C1: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BCBE118: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BCE99A4: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BD7DC92: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BD76BEF: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BBEB581: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BB03AA7: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x6339754: QOpenGLShaderProgram::link() (in /home/abusenius/qt/5.6/gcc_64/lib/libQt5Gui.so.5.6.2)
      ==30519==    by 0x5AD082E: QQuickCustomMaterialShader::compile() (qquickshadereffectnode.cpp:292)
      ==30519==    by 0x59259CD: QSGRenderContext::compile(QSGMaterialShader*, QSGMaterial*, char const*, char const*) (qsgcontext.cpp:825)
      ==30519==    by 0x58E0BCD: QSGBatchRenderer::ShaderManager::prepareMaterialNoRewrite(QSGMaterial*) (qsgbatchrenderer.cpp:185)
      
      ==30519== 913,616 (+804,576) bytes in 3,938 (+3,468) blocks are still reachable in loss record 103,276 of 103,292
      ==30519==    at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
      ==30519==    by 0x1BC8B0C1: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BCBE003: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BCD4A61: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BCD575C: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BE2EA82: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BE3059F: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BD7DBFA: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BD76BEF: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BBEB581: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x1BB03AA7: ??? (in /usr/lib/x86_64-linux-gnu/dri/i965_dri.so)
      ==30519==    by 0x6339754: QOpenGLShaderProgram::link() (in /home/abusenius/qt/5.6/gcc_64/lib/libQt5Gui.so.5.6.2)
      
      ==30519== LEAK SUMMARY:
      ==30519==    definitely lost: 24,800,010 (+563,824) bytes in 1,183 (+36) blocks
      ==30519==    indirectly lost: 4,919 (+0) bytes in 175 (+0) blocks
      ==30519==      possibly lost: 32,703,500 (+2,701,714) bytes in 81,593 (+17,869) blocks
      ==30519==    still reachable: 105,338,818 (+8,205,539) bytes in 451,731 (+41,643) blocks
      ==30519==                       of which reachable via heuristic:
      ==30519==                         newarray           : 2,203,392 (+40,176) bytes in 3,777 (+11) blocks
      ==30519==                         multipleinheritance: 226,464 (+2,624) bytes in 896 (+19) blocks
      ==30519==         suppressed: 0 (+0) bytes in 0 (+0) blocks
      

      Please provide a way to free unused shaders and other cached resources used for rendering to reduce memory footprint of embedded applications with strict memory limit.

      Attachments

        For Gerrit Dashboard: QTBUG-62392
        # Subject Branch Project Status CR V

        Activity

          People

            lagocs Laszlo Agocs
            alexbusenius Alex Busenius
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes