Code Monkey home page Code Monkey logo

Comments (16)

AlexHughesMGP avatar AlexHughesMGP commented on June 18, 2024 1

Definitely seems to be a result of the screen being locked. I tried disabling rendering when g_pSwapChain->Present(1, 0); returns DXGI_STATUS_OCCLUDED, and it drastically reduced the issue. Left shows before the change, right after, and the 5min gap between snapshots is where the screen was locked:
image
Now to figure out how to detect when it's no longer occluded. I tried checking GetClipBox, but it doesn't return NULLREGION while locked for some reason.

from imgui.

AlexHughesMGP avatar AlexHughesMGP commented on June 18, 2024 1

It does occur in the win32 dx11 example:
image
The big jump in heap size is where it was locked. The call stack again points to ImGui_ImplDX11_RenderDrawData():
image

I'll test the snippet here based on the Present() return value. I'm not familiar with how multiple viewports work so I'm not sure what an appropriate solution for the library as a whole is, but if that works it should solve the problem in my case. Thanks!

from imgui.

ocornut avatar ocornut commented on June 18, 2024 1

Your attempt as pictured in screenshot will let the rest of the code run at max speed, burning a core and essentially making no difference.

from imgui.

ocornut avatar ocornut commented on June 18, 2024 1

I have pushed ec1d2be which implement this for the DX9, DX10, DX11 and DX12 examples

DX9 and DX12 are both slightly different, and Present() does wait for vsync even on fail so it didn't exhibit a CPU core burn, but adding better support for it means we are not looping when screen locked which is desirable.

If you want to dig further into remaining issues please do but I'd prefer if you do it (or confirm it) in vanilla example. I don't know if there are ways to break into those allocs.

from imgui.

AlexHughesMGP avatar AlexHughesMGP commented on June 18, 2024

I've just noticed that the issue either only happens when the PC is locked/screen is off, or at least it gets much worse in that situation.

from imgui.

ocornut avatar ocornut commented on June 18, 2024

Thank you for the ongoing investigation :)
Could you also confirm that this happens in the unmodified/vanilla example_win32_dx11/main.cpp example?

Might or not be related, but linking to #2496 and #3907.

from imgui.

ocornut avatar ocornut commented on June 18, 2024

Now to figure out how to detect when it's no longer occluded.

Calling Present() with DXGI_PRESENT_TEST seems to be doing the job.
https://learn.microsoft.com/en-us/windows/win32/direct3ddxgi/dxgi-present

I logged WM_xxx messages and noticed that whereas minimization #2496 #3907 sends a WM_SIZE with wParam == SIZE_MINIMIZED, locking screen doesn't send any message.

[00117] WndProc 0320 wParam E3006FC7 lParam 00000001 WM_DWMCOLORIZATIONCOLORCHANGED
[00118] WndProc 0020 wParam 000C0AF6 lParam 02000002 WM_SETCURSOR
[00118] WndProc 00A0 wParam 00000002 lParam 012A06D9 WM_NCMOUSEMOVE
[00119] WndProc 0020 wParam 000C0AF6 lParam 02000002 WM_SETCURSOR
[00119] WndProc 00A0 wParam 00000002 lParam 012A06D9 WM_NCMOUSEMOVE
[00122] WndProc 0101 wParam 0000002E lParam A1530001 WM_KEYUP
[00125] WndProc 0086 wParam 00000000 lParam 00000000 WM_NCACTIVATE
[00125] WndProc 0006 wParam 00000000 lParam 00000000 WM_NCACTIVATE
[00125] WndProc 001C wParam 00000000 lParam 00000000 WM_ACTIVATEAPP
[00125] WndProc 0008 wParam 00000000 lParam 00000000 WM_KILLFOCUS
[00125] WndProc 0281 wParam 00000000 lParam C000000F WM_IME_SETCONTEXT
[00125] WndProc 0282 wParam 00000001 lParam 00000000 WM_IME_NOTIFY
[00151] WndProc 02A2 wParam 00000000 lParam 00000000 WM_NCMOUSELEAVE <-- locking around that time (maybe before, maybe after)
[13497] WndProc 001E wParam 00000000 lParam 00000000 WM_TIMECHANGE <-- notice many frames elapsed, as we went unthrolled during the lock (same problem as when minimized)
[13498] WndProc 0088 wParam 00000020 lParam 00000000 WM_SYNCPAINT
[13498] WndProc 0085 wParam 00000001 lParam 00000000 WM_NCPAINT
[13498] WndProc 0014 wParam 910126A5 lParam 00000000 WM_ERASEBKGND
[13498] WndProc 0020 wParam 000C0AF6 lParam 02000002 WM_SETCURSOR
[13498] WndProc 00A0 wParam 00000002 lParam 012A06D9 WM_NCMOUSEMOVE
[13498] WndProc 000F wParam 00000000 lParam 00000000 WM_PAINT
[13500] WndProc 0020 wParam 000C0AF6 lParam 02000002 WM_SETCURSOR
[13500] WndProc 00A0 wParam 00000002 lParam 012A06D9 WM_NCMOUSEMOVE
[13503] WndProc 0046 wParam 00000000 lParam F535F2A0 WM_WINDOWPOSCHANGING
[13503] WndProc 001C wParam 00000001 lParam 0000292C WM_ACTIVATEAPP
[13503] WndProc 0086 wParam 00000001 lParam 00000000 WM_NCACTIVATE
[13503] WndProc 0006 wParam 00000001 lParam 00000000 WM_ACTIVATE
[13503] WndProc 0281 wParam 00000001 lParam C000000F WM_IME_SETCONTEXT
[13503] WndProc 0282 wParam 00000002 lParam 00000000 WM_IME_NOTIFY
[13503] WndProc 003D wParam FFFFFFFF lParam FFFFFFFC WM_GETOBJECT
[13503] WndProc 003D wParam 00000000 lParam FFFFFFF4 WM_GETOBJECT
[13503] WndProc 0007 wParam 00000000 lParam 00000000 WM_SETFOCUS
[13503] WndProc 0020 wParam 000C0AF6 lParam 02000002 WM_SETCURSOR
[13503] WndProc 00A0 wParam 00000002 lParam 012A06D9 WM_NCMOUSEMOVE
[13557] WndProc 0020 wParam 000C0AF6 lParam 02000002 WM_SETCURSOR
[13557] WndProc 00A0 wParam 00000002 lParam 012906D9 WM_NCMOUSEMOVE
[....]

My conclusion is that we need to handle Present() rather than implement #3907 because that one will only solve minimization and not lock.

from imgui.

ocornut avatar ocornut commented on June 18, 2024

As mentioned in #2496 (comment) one of my issue with solving this based on Present() return value of main viewport, is that it would either freeze applications where main viewport is minimized and others aren't, either leave them unthrolled in that situation (which is already the case technically, but rarely noticed as io.ConfigViewportsNoDefaultParent is rarely set. However based on the premise that there is ALREADY an issue in those examples in that situation, I am not against swapping it for another issue first, while we solve the other cases.

from imgui.

ocornut avatar ocornut commented on June 18, 2024

Here's my current solution could you test it on your end?

static bool                     g_pSwapChainOccluded = false;

After polling WM message loop:

        // Handle window being occluded or screen locked
        if (g_pSwapChainOccluded && g_pSwapChain->Present(0, DXGI_PRESENT_TEST) == DXGI_STATUS_OCCLUDED)
        {
            ::Sleep(10);
            continue;
        }
        g_pSwapChainOccluded = false;

Present:

HRESULT hr = g_pSwapChain->Present(1, 0);   // Present with vsync
g_pSwapChainOccluded = (hr == DXGI_STATUS_OCCLUDED);

from imgui.

AlexHughesMGP avatar AlexHughesMGP commented on June 18, 2024

My previous attempt to fix didn't seem to work, unfortunately:
image
I'll try yours now, thanks!

from imgui.

AlexHughesMGP avatar AlexHughesMGP commented on June 18, 2024

Your solution seems to have worked, this is my result when trying with the example:
image

from imgui.

AlexHughesMGP avatar AlexHughesMGP commented on June 18, 2024

Seems to work in my case too:
image
There are still a couple of instances of the 32,903 byte object, but nowhere near as many:
image
Thanks for the help!

from imgui.

AlexHughesMGP avatar AlexHughesMGP commented on June 18, 2024

I have pushed ec1d2be which implement this for the DX9, DX10, DX11 and DX12 examples

DX9 and DX12 are both slightly different, and Present() does wait for vsync even on fail so it didn't exhibit a CPU core burn, but adding better support for it means we are not looping when screen locked which is desirable.

If you want to dig further into remaining issues please do but I'd prefer if you do it (or confirm it) in vanilla example. I don't know if there are ways to break into those allocs.

I suspect that the 32,903 byte objects are some kind of DX11 or win32 data structure which is required, because there are 2 or 3 present from the start when running normally. My guess is that they were being re-created without proper cleanup when trying to render with an occluded window, and that's no longer happening, so all is well! Thanks again.

from imgui.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.