-
-
Notifications
You must be signed in to change notification settings - Fork 10.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DX12: One frame delay of platform window size update #7152
Comments
After changing swapchain scaling from imgui/backends/imgui_impl_dx12.cpp Line 902 in 8add6bc
|
I also logged for the DX9 and DX11 backends they have the same order issue. Since they don't have scaling-stretch option for swapchain, so I did not notice the issue. So I think it should be a common issue of docking (on Windows?). |
This is intentional. PlatformRequestResize is used when resizing from Platform/OS decorations (e.g. window resizing border) which are disabled by default as Resizing Platform window from ImGui displayed decorations
Resizing Platform window from Platform/OS displayed decorations
I believe your log is partially incorrect (some incorrect recording or manipulation or missing details) ?
If I add a Sleep(80) or larger value e.g. Sleep(200) you can notice that the error only happens for very short while (at least on my setup), not for 200 ms. So it doesn't make it any "easier" to see the issue with Sleep(200), it's equally easy in both situation. Does it on your? Right after |
Additional comments: I think this issue seems new to me, I don't recall seeing when initially implementing multi-viewport for the DX12 backend, and I believe it may also be due to some DX12/Windows version/SDK version/drivers subtleties which I don't quite understand now. Note that DX12 backend also have a "flicker" when dragging a viewport outside, it doesn't appear as far as with other backends, and that's perhaps related to the same underlying thing. |
Hi @ocornut , Thank you so much for the investigation and explanation. I have uploaded the testing code for you to check: (Edit: commit updated) devkaiwang@21c4f82 Here is the screenshot of the logs happened when I dragged the border of the "Hello world!" platform window when it was a standalone window out of the main viewport: As you could see from the log, if (viewport->PlatformRequestResize)
{
viewport->Size = viewport->LastPlatformSize = g.PlatformIO.Platform_GetWindowSize(viewport);
// Debug only:
char log[1024];
std::snprintf(log, sizeof(log), "Viewport size update, size=(%u, %u)\n",
static_cast<uint32_t>(viewport->Size.x), static_cast<uint32_t>(viewport->Size.y));
OutputDebugStringA(log);
} If my debug is correct, To me, it seems ImGui was rendering in old size but the swapchain was in new size, causing the ghosting stretch effect.
I commented out
From my observation, Sleep(200) seems to help reproduce the issue better if I revert the swapchain scaling mode to stretch. |
The resizing borders of PLATFORM WINDOWS don't appears by default, don't appear in your first-post video, and don't appear in devkaiwang@21c4f82#diff-66e3146b58f2d5a61041ee73d7320664a6028a7eccc468df72166822b09ea976 (unless you modified things to set You are exactly the situation described in my "Resize from ImGui decorations -> point 3" and your log matches that. PS: You can use char log[1024];
std::snprintf(log, sizeof(log), "Swapchain update, size=(%u, %u)\n",
static_cast<uint32_t>(size.x), static_cast<uint32_t>(size.y));
OutputDebugStringA(log); Becomes: IMGUI_DEBUG_LOG("Swapchain update, size=(%u, %u)\n", (uint32_t)size.x, (uint32_t)size.y); Appears in console and
It's difficult to compare without a video as it may depends on OS/drivers/GPU and other settings. |
Hi @ocornut Thanks for the reply!
I'm not sure if I totally understand this but I can use my mouse to resize the platform window as you could see from the video, though the window is not in thick border style of Windows platform.
This is the problem I'm trying to understand. As you can see from my log, there is no
Sorry missed this useful function. Thanks for the education. |
You are resizing from imgui displayed borders and using imgui resizing logic, not from Windows displayed borders using Windows code. They are two different paths. Windows has its own resizing logic. In your situation it is not used because the Windows borders are hidden
point 2 refer to a different location in the code inside Begin(), where you didn’t add a log entry. If you search for “viewport->Size = “ you will find it. |
Interestingly our example app had an extraneous back buffer, which was reduced in 6684984, and reducing it fixed the flickering I described here (which is not your issue, but, read on). The While this is not the same as your issue, my understanding based on previous messages and your description is that your issue had to do with frame backbuffers being queued and appearing too late. What it effectively means is that user of setups with unusual amount of frame latency should probably delay update of "size" perceived by imgui code, according to this latency. In single-viewport mode (explaining this for simplicity) we do: void ImGui_ImplWin32_NewFrame()
{
RECT rect = { 0, 0, 0, 0 };
::GetClientRect(bd->hWnd, &rect);
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));
... It would need to be changed to a system where the value is "queued" and delayed slightly. In multi-viewport mode the code: if (viewport->PlatformRequestResize)
viewport->Size = viewport->LastPlatformSize = g.PlatformIO.Platform_GetWindowSize(viewport); Should do the same. Otherwise, it means your code running during Frame N sees Frame N size, and may render e.g. scaled contents, but this scaled contents will only appear on screen on Frame N+1 or N+2, and what appears on Frame N is the contents from Frame N-2 or N-1. This is purely theoretical, I would likely need to testbed to investigate this more thoroughly. |
Version Info:
My Issue/Question:
When we dragging and resizing a dock window (Platform Window), there is one frame delay of the update of the window size for dock window.
I put logs in these places to show the order:
ImGui_ImplDX12_SetWindowSize
where framebuffers recreated due to new size.ImGui_ImplWin32_WndProcHandler_PlatformWindow
whereWM_SIZE
event got handled.Here is the log and I added extra comments using
//
. (293,692) is the size of the window when resizing.In fact, as the order is incorrect,
PlatformRequestResize
flag is cleared inImGuiViewportP::ClearRequestFlags()
before it can actually be used to trigger the resize work.Screenshots/Video
By adding a sleep in the main loop to make the refresh rate low, issue can be seen easily.
Screen record:
platform_window_resizing.mp4
The text was updated successfully, but these errors were encountered: