Skip to content
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

Possible to get the capture texture from the framepool on init? #71

Closed
MartinClementson opened this issue Oct 9, 2020 · 2 comments
Closed

Comments

@MartinClementson
Copy link

Hello,

Is it possible to get a reference to the Texture from the Framepool outside of the frame arrived function?

I have implemented OpenGL interop with my capture. At the moment I've made the back buffer a shared resource with OpenGL, when I receive a new frame, I copy to the back buffer, and then use it in OpenGL. However, I would like not to have to do the copy to the back buffer because that kind of defeat the optimization that the glInterop is supposed to provide to my app.

So I would like to set up the interop to share the resource with the texture in the Framepool.

I would like to achieve the following in my init code:

Psuedo example (Not real code)

m_framePool  = Direct3D11CaptureFramePool::Create(...) 

//Get the texture from a frame object.
framePoolTexure =GetDXGIInterfaceFromObject<ID3D11Texture2D> (m_framePool.GetFrameObject(index).Surface().get())

//Share with openGL
openGLInteropSharedTexHandle = CreateOpenGLSharedResource(openGLTexture,framePoolTexure )

//Create session
  m_session = m_framePool.CreateCaptureSession(m_item);
 m_framePool.FrameArrived(winrt::auto_revoke,{ this, &myClass::OnFrameArrived });

On top of this, there is one more thing that's needed for this to work, and that is that the parameters of the frame texture are compatible with the OpenGL interop. If I create my own texture I have control over these things. But I have no knowledge of what parameters the frame pool textures are created with. Is that something you have documented somewhere which you could share with me? I am aware that I might be chasing something that's not even possible for this reason.

Thanks for all the great work you do and thanks for the help!
M

@robmikh
Copy link
Member

robmikh commented Oct 10, 2020

Keep in mind that the frame pool represents shared textures between your application and the DWM. We don't allow applications indiscriminate access to the underlying textures because we wouldn't be able to guarantee that they aren't currently being drawn to by the compositor. This is also why you should never cache the texture we provide. However, as long as you are holding onto the Direct3D11CaptureFrame object, the texture is yours. When you're done with it, call Close/Dispose (for C++/C# respectively) to return the frame back to the frame pool. Although I'm not familiar with OpenGL/DirectX interop, so I can't advice if it's safe to create interop handles for each frame pool texture.

Unfortunately, I think you won't be able to avoid the copy here. I would create one interop texture that matches the dimensions of the frame pool's textures and copy frames into that texture when frames arrive. Then you can turn around and draw the contents of the interop texture using OpenGL.

@MartinClementson
Copy link
Author

Thank you for taking the time to answer, Robert.

I agree that it's best not to expose the underlying textures outside of the controlled way it's being done now with TryGetNextFrame, most times than not it would probably cause issues. I guess my issue lies more with the interop. Technically I think that it should work if I create the interop on the frame pool textures and ensure that they are not being modified outside of the newFrameCallback, but only if A) The underlying textures are created with flags that are supported, B) the ID3D11Texture2D object returned by getFrame stays the same in memory so that it will always be the same I get from the frame.

I suspect that it's A) that fails here. I suppose I'll leave it as it is, the CopyResource function doesn't move it to the CPU in the end so the overhead is not that bad I suppose, the bottleneck lies somewhere else.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants