imgui icon indicating copy to clipboard operation
imgui copied to clipboard

low ms/frame when sharing/recording screen

Open akosil opened this issue 1 year ago • 6 comments

Version/Branch of Dear ImGui:

v1.91.6 WIP , docking branch

Back-ends:

imgui_impl_dx11

Compiler, OS:

Windows 10

Full config/build information:

example_win32_directx11 build from v1.91.6 WIP - docking branch

Details:

high ms / frame (worse performance) when sharing screen on discord or recording screen with OBS

Screenshots/Video:

image

Minimal, Complete and Verifiable Example code:

-

akosil avatar Dec 09 '24 14:12 akosil

You would need to investigate this on your own but it seems like a problem of your recording software, if not a feature (perhaps they are hijacking something to make vsync simulate 20 hz, is the 20 fps framerate stable?) Maybe try with different examples/backends.

ocornut avatar Dec 09 '24 14:12 ocornut

I will try to find the issue. Another issue i found: When I undock a window and move it outside the main viewport, the main application experiences higher ms/frame (worse performance). Is this expected behavior, or could it be a bug?

akosil avatar Dec 11 '24 03:12 akosil

Is that also when recording? What sort of ms/frame amount does it goes from and to ?

We create new windows and swapchains so there is a cost but normally it should be relatively negligible. It’s related to your first question because our examples app are fully throttled using a vsync wait, and that may be affected by drivers and other sources.

ocornut avatar Dec 11 '24 08:12 ocornut

2nd issue is without recording: Application is running on main screen (240hz). If I move out a window to main screen, with vsync on actually I get slightly higher FPS right now, but without vsync the performance drop is visible. If I move out a window to second screen(60hz), I always get a way worse performance. If I change the hz from 240 to 60, I get same performance drop wherever I undock the window.

ms/frame values without vsync: normal, no undock: 3.284 ms / frame undock from main screen to main screen: 5.912 ms / frame undock from main screen to second screen: 9.253 ms / frame

I attached an image for reference: With vsync image Without vsync image

akosil avatar Dec 11 '24 11:12 akosil

Profiling would be needed, but unfortunately this can be due to so many things:

  • drivers
  • drivers settings related to vsync
  • possibly swapchain swapeffect

One thing that may be worth trying

  • change the SwapChain setup from
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

to

sd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;

And the other more modern FLIP modes. For this to work:

  • you need to ensure the project is built with Windows 10+ SDK (by default our vsproj are committed with SDK 8.1, need Visual Studio to upgrade them to SDK 10.
  • need to change it in example_win32_directx11/main.cpp AND in backends/imgui_impl_win32.cpp's ImGui_ImplDX11_CreateWindow() function.

I would be curious to know if it makes a difference for you. If it does it may be tempting to migrate committed examples to rely on SDK 10 + make backend inherit SwapEffect.

ocornut avatar Dec 11 '24 13:12 ocornut

Sorry for late reply, I tried sd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;

but in this case my overlay wont work. It will be a fullscreen non-transparent window and also fps drop will still be present.

wc = { sizeof(WNDCLASSEX), ACS_TRANSPARENT, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, wsApplicationName.c_str(), NULL };
::RegisterClassEx(&wc);
hwnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_TRANSPARENT | WS_EX_NOACTIVATE, wc.lpszClassName, wsApplicationName.c_str(), WS_POPUP, 0, 0, config.window_width, config.window_height, NULL, NULL, wc.hInstance, NULL);

MARGINS margins = { -1 };
DwmExtendFrameIntoClientArea(hwnd, &margins); //make transparent

...

if (config.isOverlay) {
    SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); //ws popup mod
    ::ShowWindow(hwnd, SW_NORMAL);
}
else {
    ::ShowWindow(hwnd, SW_SHOWDEFAULT);
}

Has to be OS/driver related issue. My app with OBS/discord share works on my another pc for example.

akosil avatar Apr 13 '25 23:04 akosil

While optimizing my app, I noticed that once the game starts, the ImGui-based app's frame rate drops from ~4.5 ms/frame to ~7.5 ms/frame, even when all ImGui UI and backend logic are completely disabled.

To investigate further, I ran OBS alongside it. With OBS recording, the frame time dropped significantly to ~60 ms/frame. However, the game has an option to limit its own FPS. When I limited it to 30 FPS, my ImGui app returned to ~5 ms/frame, even with the game and OBS running.

I also tested OBS separately. When OBS is open and actively previewing the screen, my ImGui app’s frame rate drops. But when I minimize OBS, the frame rate returns to normal.

This suggests that the issue isn’t caused by ImGui itself, but rather by competition for GPU resources between the game, OBS, and the ImGui app.

Recap regarding ImGui docking windows, the frame rate drops when I undock a window and move it into another monitor, specifically one running at 60 Hz. The same frame rate drop occurs if I move the entire ImGui app window into the 60 Hz monitor. However, if I keep everything (docked or undocked) within the main 240 Hz monitor, there is no frame rate drop.

Additionally, if I move the OBS window into the same 240 Hz monitor where the ImGui app is running, I experience no frame rate drop at all.

This suggests the frame rate degradation may be related to mixed-refresh multi-monitor setups, possibly due to VSync behavior across displays with different refresh rates, rather than any issue with ImGui itself.

akosil avatar Jun 20 '25 21:06 akosil