low ms/frame when sharing/recording screen
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:
Minimal, Complete and Verifiable Example code:
-
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.
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?
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.
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
Without vsync
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.
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.
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.