Skip to content

Created resize function to avoid recreating multiple LAppSpriteShaders.#50

Merged
wada-at-live2d-com merged 2 commits intoLive2D:developfrom
KhangPham9:bugfix-resize-memory-leak
Jul 15, 2025
Merged

Created resize function to avoid recreating multiple LAppSpriteShaders.#50
wada-at-live2d-com merged 2 commits intoLive2D:developfrom
KhangPham9:bugfix-resize-memory-leak

Conversation

@KhangPham9
Copy link
Copy Markdown
Contributor

I found a memory leak in the Sample Code for OpenGL Linux when the user resizes the window. This could also apply to the other OpenGL samples, but I have only looked at the Linux one.

When the window is resized, a call to the LAppView::Initialize(int width, int height) function is made and there are calls to make new LAppSpriteShader objects without a delete.

I ran the program under valgrind and my steps and output are recorded below:
Steps to reproduce:

  1. Get a version of CubsimSDKForNative-5-r.4
  2. Compile the OpenGL Sample for Linux
  3. Choose the Full option when running the build script (never tested on minimum)
  4. Run valgrind as follows: valgrind -s --leak-check=full --track-origin=yes ./Demo
  5. Resize the window.
  6. Close the window when desired.

Valgrind output:
==71014==
==71014== HEAP SUMMARY:
==71014== in use at exit: 94,079 bytes in 1,053 blocks
==71014== total heap usage: 66,634 allocs, 65,581 frees, 1,058,055,882 bytes allocated
==71014==
==71014== 4 bytes in 1 blocks are definitely lost in loss record 1 of 175
==71014== at 0x483BE63: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==71014== by 0x13AF59: LAppView::Initialize(int, int) (in /home/khang/Live2D/CubismSdkForNative-5-r.4/Samples/OpenGL/Demo/proj.linux.cmake/build/make_gcc/bin/Demo/Demo)
==71014== by 0x124736: LAppDelegate::Initialize() (in /home/khang/Live2D/CubismSdkForNative-5-r.4/Samples/OpenGL/Demo/proj.linux.cmake/build/make_gcc/bin/Demo/Demo)
==71014== by 0x121C34: main (in /home/khang/Live2D/CubismSdkForNative-5-r.4/Samples/OpenGL/Demo/proj.linux.cmake/build/make_gcc/bin/Demo/Demo)
==71014==
==71014== 240 bytes in 60 blocks are definitely lost in loss record 139 of 175
==71014== at 0x483BE63: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==71014== by 0x13AF59: LAppView::Initialize(int, int) (in /home/khang/Live2D/CubismSdkForNative-5-r.4/Samples/OpenGL/Demo/proj.linux.cmake/build/make_gcc/bin/Demo/Demo)
==71014== by 0x124112: LAppDelegate::Run() (in /home/khang/Live2D/CubismSdkForNative-5-r.4/Samples/OpenGL/Demo/proj.linux.cmake/build/make_gcc/bin/Demo/Demo)
==71014== by 0x121C4E: main (in /home/khang/Live2D/CubismSdkForNative-5-r.4/Samples/OpenGL/Demo/proj.linux.cmake/build/make_gcc/bin/Demo/Demo)
==71014==
==71014== 408 bytes in 1 blocks are definitely lost in loss record 148 of 175
==71014== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==71014== by 0x4FB5D1F: _XimOpenIM (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==71014== by 0x4FB595D: _XimRegisterIMInstantiateCallback (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==71014== by 0x4F9C94C: XRegisterIMInstantiateCallback (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==71014== by 0x16DBA1: _glfwInitX11 (in /home/khang/Live2D/CubismSdkForNative-5-r.4/Samples/OpenGL/Demo/proj.linux.cmake/build/make_gcc/bin/Demo/Demo)
==71014== by 0x162B9F: glfwInit (in /home/khang/Live2D/CubismSdkForNative-5-r.4/Samples/OpenGL/Demo/proj.linux.cmake/build/make_gcc/bin/Demo/Demo)
==71014== by 0x1245B0: LAppDelegate::Initialize() (in /home/khang/Live2D/CubismSdkForNative-5-r.4/Samples/OpenGL/Demo/proj.linux.cmake/build/make_gcc/bin/Demo/Demo)
==71014== by 0x121C34: main (in /home/khang/Live2D/CubismSdkForNative-5-r.4/Samples/OpenGL/Demo/proj.linux.cmake/build/make_gcc/bin/Demo/Demo)
==71014==
==71014== LEAK SUMMARY:
==71014== definitely lost: 652 bytes in 62 blocks
==71014== indirectly lost: 0 bytes in 0 blocks
==71014== possibly lost: 0 bytes in 0 blocks
==71014== still reachable: 93,427 bytes in 991 blocks
==71014== suppressed: 0 bytes in 0 blocks
==71014== Reachable blocks (those to which a pointer was found) are not shown.
==71014== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==71014==
==71014== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)

As you can see valgrind complains about a memory leak in the LAppView::Initialize(int, int) function. My proposed solution is to create a separate function called resize that doesn't create a new LAppSpriteShader.

Here are the valgrind results after my changes:
==71160==
==71160== HEAP SUMMARY:
==71160== in use at exit: 93,835 bytes in 992 blocks
==71160== total heap usage: 106,813 allocs, 105,821 frees, 1,253,206,505 bytes allocated
==71160==
==71160== 408 bytes in 1 blocks are definitely lost in loss record 146 of 173
==71160== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==71160== by 0x4FB5D1F: _XimOpenIM (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==71160== by 0x4FB595D: _XimRegisterIMInstantiateCallback (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==71160== by 0x4F9C94C: XRegisterIMInstantiateCallback (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==71160== by 0x16DC51: _glfwInitX11 (in /home/khang/CubismNativeSamples/Samples/OpenGL/Demo/proj.linux.cmake/build/make_gcc/bin/Demo/Demo)
==71160== by 0x162C4F: glfwInit (in /home/khang/CubismNativeSamples/Samples/OpenGL/Demo/proj.linux.cmake/build/make_gcc/bin/Demo/Demo)
==71160== by 0x124630: LAppDelegate::Initialize() (in /home/khang/CubismNativeSamples/Samples/OpenGL/Demo/proj.linux.cmake/build/make_gcc/bin/Demo/Demo)
==71160== by 0x121C54: main (in /home/khang/CubismNativeSamples/Samples/OpenGL/Demo/proj.linux.cmake/build/make_gcc/bin/Demo/Demo)
==71160==
==71160== LEAK SUMMARY:
==71160== definitely lost: 408 bytes in 1 blocks
==71160== indirectly lost: 0 bytes in 0 blocks
==71160== possibly lost: 0 bytes in 0 blocks
==71160== still reachable: 93,427 bytes in 991 blocks
==71160== suppressed: 0 bytes in 0 blocks
==71160== Reachable blocks (those to which a pointer was found) are not shown.
==71160== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==71160==
==71160== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR addresses a memory leak that occurred during window resizing by separating the resizing logic into a new function that avoids re-creating the LAppSpriteShader object.

  • Added a new ResizeWindow method in LAppView.hpp and its implementation in LAppView.cpp that calls the base class initializer without instantiating a new shader.
  • Updated LAppDelegate.cpp to call ResizeWindow instead of the original Initialize on window resize.

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
Samples/OpenGL/Demo/proj.linux.cmake/src/LAppView.hpp Added the declaration of the new ResizeWindow method
Samples/OpenGL/Demo/proj.linux.cmake/src/LAppView.cpp Implemented ResizeWindow without creating new shader
Samples/OpenGL/Demo/proj.linux.cmake/src/LAppDelegate.cpp Updated to call ResizeWindow on window size change
Comments suppressed due to low confidence (2)

Samples/OpenGL/Demo/proj.linux.cmake/src/LAppView.hpp:56

  • Consider updating the comment for ResizeWindow to indicate that this method intentionally avoids recreating the LAppSpriteShader to prevent memory leaks.
    /**

Samples/OpenGL/Demo/proj.linux.cmake/src/LAppView.cpp:82

  • Add a comment in the ResizeWindow implementation noting that it calls the base class initializer to update the view dimensions while deliberately avoiding a new instantiation of LAppSpriteShader to prevent recurrence of the memory leak.
void LAppView::ResizeWindow(int width, int height)

@wada-at-live2d-com
Copy link
Copy Markdown
Contributor

@KhangPham9

Thank you for the bug report!
We apologize for the delayed response.

We can confirm that in our environment, multiple LAppSpriteShaders are being created in OpenGL on Linux.
We will merge this PR and continue to check for impacts on other platforms and work on improvements.

@wada-at-live2d-com wada-at-live2d-com merged commit bd0536f into Live2D:develop Jul 15, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants