Code Monkey home page Code Monkey logo

Comments (10)

jpark37 avatar jpark37 commented on May 18, 2024

I ask because we're hearing infrequent reports of shutdown hangs, and I'm wondering if this is the reason.

from windows.ui.composition-win32-samples.

robmikh avatar robmikh commented on May 18, 2024

When the frame pool is created with Direct3D11CaptureFramePool::Create, we use the DispatcherQueue to fire the frame arrived event to the thread that created the frame pool. I could have sworn calling Create without a dispatcher queue present would cause us to blow up in an internal call. Although testing it now, this behavior seems to have regressed...

Regardless, the most important part of the DispatcherQueue requirement is that you are pumping messages on that thread. As long as you're doing that, I wouldn't expect it to be the problem. Usually when I see odd behavior on tear-down, it was because I wasn't properly initializing COM on the thread. This can cause odd life-time related bugs, and may be what you're seeing but I can't be certain.

I know that you mentioned hearing infrequent reports of this, but if you get a consistent repro or a memory dump when this happens I can take a look.

from windows.ui.composition-win32-samples.

robmikh avatar robmikh commented on May 18, 2024

Additionally, I would recommend creating a DispatcherQueue for your thread by calling CreateDispatcherQueueController. The fact that it's working without it has me a bit concerned about if the system changes in the future.

Or you can forgo the dispatcher requirement all together and use Direct3D11CaptureFramePool::CreateFreeThreaded, and then use your own mechanism to marshal the frame to a thread of your choosing.

from windows.ui.composition-win32-samples.

jpark37 avatar jpark37 commented on May 18, 2024

I can let a dispatcher queue live for the life of the thread. For simplicity, we do all WGC things on our render thread since we have that's where our D3D11 renderer operates. I suppose this would be advised?

void render_thread()
{
    // Add dispatcher queue here.
    queue = ...

    while (running) {
        tick sources, possibly create/destroy WGC captures
        render sources
        pump win32 messages until empty <- frame arrival callback, D3D11 texture copy here
    }

    // Let queue fall out of scope I guess?
}

We have a separate message pump that lives on the main thread that is implicit to Qt. Hopefully these aren't fighting each other, but my Win32/COM knowledge isn't that strong. The render thread pump was added recently just to support WGC.

I can find out if we have any memory dumps.

from windows.ui.composition-win32-samples.

robmikh avatar robmikh commented on May 18, 2024

That sounds reasonable to me, and having the two different pumps on two different threads should be ok. The only thing I would add is that I would add a call to RoInitialize (or in your case, winrt::init_apartmnet, since you seem to be using C++/WinRT) before interacting/activating any WinRT objects on that thread.

from windows.ui.composition-win32-samples.

jpark37 avatar jpark37 commented on May 18, 2024

Thanks, you reminded me I didn't set up the winrt apartment either. I also noticed we were keeping WGC objects alive across render threads (we kill and recreate the thread in some situations), so I added a fix to destroy on thread stop and recreate on thread start. Hopefully everything is robust and stable now.

from windows.ui.composition-win32-samples.

notr1ch avatar notr1ch commented on May 18, 2024

I have a couple of memory dumps from the shutdown freezes we experienced, these are full heap dumps so I don't want to link them publicly. The WGC thread was stuck in a COM call to the "Capture Service" process. Debugging the service showed no stuck threads, almost like it wasn't aware of the COM call.

rpcrt4!LRPC_BASE_CCALL::DoSendReceive+0x112
rpcrt4!LRPC_CCALL::SendReceive+0x51
rpcrt4!I_RpcSendReceive+0x6f
combase!CMessageCall::CallI_RpcSendReceive+0x30 [onecore\com\combase\dcomrem\call.cxx @ 3956] 
combase!ThreadSendReceive+0xf0 [onecore\com\combase\dcomrem\channelb.cxx @ 7316] 
combase!CSyncClientCall::SwitchAptAndDispatchCall+0xa0 [onecore\com\combase\dcomrem\channelb.cxx @ 5742] 
combase!CSyncClientCall::SendReceive2+0x182 [onecore\com\combase\dcomrem\channelb.cxx @ 5377] 
combase!SyncClientCallRetryContext::SendReceiveWithRetry+0x25 [onecore\com\combase\dcomrem\callctrl.cxx @ 1617] 
combase!CSyncClientCall::SendReceiveInRetryContext+0x25 [onecore\com\combase\dcomrem\callctrl.cxx @ 567] 
combase!DefaultSendReceive+0x64 [onecore\com\combase\dcomrem\callctrl.cxx @ 525] 
combase!CSyncClientCall::SendReceive+0x128 [onecore\com\combase\dcomrem\ctxchnl.cxx @ 783] 
combase!CClientChannel::SendReceive+0x84 [onecore\com\combase\dcomrem\ctxchnl.cxx @ 653] 
combase!NdrExtpProxySendReceive+0x4e [onecore\com\combase\ndr\ndrole\proxy.cxx @ 2002] 
rpcrt4!NdrpClientCall3+0x395
combase!ObjectStublessClient+0x13b [onecore\com\combase\ndr\ndrole\amd64\stblsclt.cxx @ 369] 
combase!ObjectStubless+0x42 [onecore\com\combase\ndr\ndrole\amd64\stubless.asm @ 176] 
GraphicsCapture!winrt::Windows::Graphics::Capture::implementation::ServerCaptureSessionCore::StopCapture+0x15
GraphicsCapture!winrt::Windows::Graphics::Capture::implementation::GraphicsCaptureSession::Close+0x34
GraphicsCapture!winrt::impl::produce<winrt::Windows::Graphics::Capture::implementation::GraphicsCaptureSession,winrt::Windows::Foundation::IClosable>::Close+0x1f
libobs_winrt!winrt::impl::consume_Windows_Foundation_IClosable<winrt::Windows::Graphics::Capture::GraphicsCaptureSession>::Close+0x26 [c:\program files (x86)\windows kits\10\include\10.0.18362.0\cppwinrt\winrt\windows.foundation.h @ 17] 
libobs_winrt!winrt_capture_free+0xa3 [d:\obs2\libobs-winrt\winrt-capture.cpp @ 453] 
win_capture!wc_tick+0xb6 [d:\obs2\plugins\win-capture\window-capture.c @ 402] 
obs!obs_source_video_tick+0x1a2 [d:\obs2\libobs\obs-source.c @ 1159] 
obs!tick_sources+0x103 [d:\obs2\libobs\obs-video.c @ 71] 
obs!obs_graphics_thread+0x204 [d:\obs2\libobs\obs-video.c @ 905] 
w32_pthreads!ptw32_threadStart+0x8a [d:\obs2\deps\w32-pthreads\ptw32_threadstart.c @ 225] 
ucrtbase!thread_start<unsigned int (__cdecl*)(void *),1>+0x42
kernel32!BaseThreadInitThunk+0x14
ntdll!RtlUserThreadStart+0x21```

from windows.ui.composition-win32-samples.

robmikh avatar robmikh commented on May 18, 2024

Thanks, @notr1ch! It would be interesting to know if this still happens after initializing COM on the thread. If the proxy stub is blocked and the service is unaware of it, it might be an initialization issue.

If it persists, we can maybe talk through another channel about looking at the dump if you feel comfortable. A dump of the capture service would be interesting as well.

from windows.ui.composition-win32-samples.

robmikh avatar robmikh commented on May 18, 2024

Closing this issue. If you still see this after properly initializing COM, please let us know.

from windows.ui.composition-win32-samples.

jpark37 avatar jpark37 commented on May 18, 2024

We added the DispatchQueue and RoInitialize call, and we haven't seen the problem since, so we're probably good now.

I also added code to disable the yellow border recently, but I had to switch our thread from STA to MTA to get rid of the assert from blocking on the RequestAccessAsync result in-place. Do you think this is fine?

from windows.ui.composition-win32-samples.

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.