imgui: Memory leak with with viewports when using OpenGL3 backend

Dear ImGui 1.84 WIP (18307)
--------------------------------
sizeof(size_t): 4, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=199711
define: _WIN32
define: _MSC_VER=1929
define: _MSVC_LANG=201402
define: IMGUI_HAS_VIEWPORT
define: IMGUI_HAS_DOCK
--------------------------------
io.BackendPlatformName: imgui_impl_glfw
io.BackendRendererName: imgui_impl_opengl3
io.ConfigFlags: 0x00000441
 NavEnableKeyboard
 DockingEnable
 ViewportsEnable
io.ConfigViewportsNoDecoration
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x00001406
 HasMouseCursors
 HasSetMousePos
 PlatformHasViewports
 RendererHasViewports
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,64
io.DisplaySize: 1280.00,720.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 8.00,8.00
style.WindowBorderSize: 1.00
style.FramePadding: 4.00,3.00
style.FrameRounding: 0.00
style.FrameBorderSize: 0.00
style.ItemSpacing: 8.00,4.00
style.ItemInnerSpacing: 4.00,4.00

My Issue/Question:

When using the opengl3 backend with viewports enabled there is a memory leak of a couple of MB per second after dragging a window outside the main viewport. It recovers if the windows is dragged back into the main viewport. I can reproduce with both example_sdl_opengl3 and example_glfw_opengl3. It does not happen with the opengl2 backend.

To reproduce: start the example, drag the “Hello, world!” window out of the viewport.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 37 (21 by maintainers)

Commits related to this issue

Most upvoted comments

Kind of tricky doing anything when the main viewport isn’t rendering, so I did bool is_main = ImGui::GetMainViewport() == draw_data->OwnerViewport; and used is_main as an additional condition in the two loops in ImGui_ImplOpenGL3_RenderDrawData(). It is definitely the glBufferData calls. I assume the calling pattern with multiple viewports makes the driver keep around old buffers for some reason.

I have very little experience with OpenGL, so I’m not sure it’s anywhere near correct, but this hack seems to fix it:

    static GLsizeiptr v_max_size = 0;
    auto v_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert);
    if (v_size > v_max_size) {
      v_max_size = v_size;
      glBufferData(GL_ARRAY_BUFFER, v_max_size, NULL, GL_STREAM_DRAW);
    }
    static GLsizeiptr i_max_size = 0;
    auto i_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx);
    if (i_size > i_max_size) {
      i_max_size = i_size;
      glBufferData(GL_ELEMENT_ARRAY_BUFFER, i_max_size, NULL, GL_STREAM_DRAW);
    }
    // Upload vertex/index buffers
    glBufferSubData(GL_ARRAY_BUFFER, 0, v_size, (const GLvoid *)cmd_list->VtxBuffer.Data);
    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, i_size, (const GLvoid *)cmd_list->IdxBuffer.Data);

It should probably be done in some nicer way.

The state for me is that I can no longer reproduce the memory leak, even with the code as it was when I originally reported this. I guess the Intel driver has been updated to fix the problem.

The tearing issue is still there if UseBufferSubData is true, and not there if set to false.

GL_DYNAMIC_DRAW vs GL_STREAM_DRAW seems to make no difference.

Output from debug printouts:

GL_MAJOR_VERSION = 3
GL_MINOR_VERSION = 0
GL_VENDOR = 'Intel'
GL_RENDERER = 'Intel(R) UHD Graphics'

@ocornut hi I find a new bug in features/opengl_buffer_update,What do you think of this

Version: dear imgui, v1.84 WIP Branch: features/opengl_buffer_update

Back-ends: imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp Compiler: Visual Studio 2019 Operating System: Windows 10 My GPU: GeForce GTX 1050 Ti Version:457.49

The following bug occurs when using DockerSpace when the Dear ImGui Demo window is initialized outside

dd

@ocornut thanks, My computer works fine on features/opengl_buffer_update

Version: dear imgui, v1.84 WIP Branch: features/opengl_buffer_update

Back-ends: imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp Compiler: Visual Studio 2019 Operating System: Windows 10

My GPU: GeForce GTX 1050 Ti Version:457.49

@AidanSun05 I presume @parbo is referring to an actual leak, as per the “a couple MB per second” comment.

It’s probably highly dependent on the GPU driver and platform and there might be a possibility that updating drivers could fix it. OpenGL tends to be poorly supported. Even if the drivers are faulty, it would also really be worthwhile to investigate the cause.

For what it is worth, on my home laptop I do not see a memory increase in that window.

We get that sort of stuff mentioned from time to time (e.g. #3381 and #2981) but nobody with a repro could investigate further.

I think this is what you’re talking about:

image

This extra memory allocation is for supporting a second platform context for the window that was just dragged out, and I’m pretty sure there’s no leak. A memory leak is when a process doesn’t deallocate its memory when it terminates. In the case of multi-viewports, the memory graph dipped down shortly after the window was dragged back into the viewport. This indicates that the extra memory was freed correctly, making it not leaked.