-
Notifications
You must be signed in to change notification settings - Fork 32
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
Zero copy and get direct3d device and context #90
Conversation
It looks good, but the only problem I see is having RawDirect3DDevice in the new function parameters. I think this is unnecessary for most people. Do you have any less verbose way to get this? |
I've actually thought about this, I actually wanted to implement getting the device and context without breaking the existing api at first, but the existing api looks harder to implement. 1, it's the kind I'm implementing now, by passing one more parameter. 2, Do a little wrapping of pub struct Context<T> {
pub flags: T,
pub device: ID3D11Device,
pub context: ID3D11DeviceContext,
}
pub trait GraphicsCaptureApiHandler: Sized {
// Omission of other statements...
fn new(ctx: Context<Self::Flags>) -> Result<Self, Self::Error>;
} 3, In Settings, the external can pass the device and context by itself, and windows-capture can use the externally provided device instead of creating it by itself. @NiiightmareXD In my opinion, the first and second are the best, and the third, while feasible, brings a lot of uncontrollable factors with externally created devices, so which do you think is better, or is there a better way to do it. |
The first one would be the best but I also like the second one |
@NiiightmareXD So keep this pull request as is? |
I'm looking into ways so the function could accept either 1 or 2 arguments and be a generic but I think this is also good, do you want to change anything? Should I merge? |
I think the |
it's done. |
Zero copy texture
First, get
ID3D11Texture2D
directly viaFrame
, without making a copy internally, and just return the texture in the current frame.https://github.com/mycrl/windows-capture/blob/main/src/frame.rs#L181
Then, it's not really necessary to clone once to get surface and texture, although
ID3D11Texture2D
andIDirect3DSurface
are actually pointers internally, and it doesn't really matter if you return a reference or not, I think it's good to return a reference to clarify the semantics, and to indicate that surface and texture are only available during the current frame's lifetime.Also I removed the CPU write flag for textures, because for the usage scenario here, there is no need to make the CPU writable to the texture, only readable, and keeping only the read flag makes it easier for the Direct3D underlayer to deal with resource mutexes and improve performance, Because if it is possible to write, the underlayer needs to think more about resource contention and introduce unnecessary locks or similar mechanism.
https://github.com/mycrl/windows-capture/blob/main/src/frame.rs#L205
External access to Direct3D devices and contexts
Then there's the second big change, adding a
RawDirect3DDevice
parameter to thenew
method of theGraphicsCaptureApiHandler
trait.https://github.com/mycrl/windows-capture/blob/main/src/capture.rs#L516
First, let me explain why this parameter is needed. In direct3d11, devices and contexts are independent, if windows-capture doesn't expose its own devices and contexts, then external parties can't use your textures or have a hard time using your textures, of course, external parties can use the software buffers, but this goes against the zero-copy and performance-first principles.
For example, if you need to use the texture directly for some post-processing, scaling and texture format conversion needs, the only way to do this is to keep creating cross-device shared resource handles for each frame. At the same time, creating shared resource handles for each frame is also a high overhead operation (acceptable when both sides are using dx11).
Therefore, it is necessary to perform this operation in windows-capture's own device and context, because the library aims for high performance and you need to enable users to use your library in a high performance way.