Skip to content
This repository has been archived by the owner on Oct 26, 2023. It is now read-only.

Transparency (no back buffer support) using CreateSwapChainForComposition contribution #29

Closed
Ciantic opened this issue Mar 2, 2021 · 2 comments

Comments

@Ciantic
Copy link

Ciantic commented Mar 2, 2021

I just did transparency support to druid which also uses D2D and swapchains and WS_EX_NOREDIRECTIONBITMAP, I followed this tutorial to achive that.

I think I could create similar method for this library the same way as create_swapchain_for_hwnd was done.

My idea is to do additional method like create_swapchain_with_composition_for_hwnd which could be used to do modern performant transparent windows.

It needs to create necessary resources to bind the swapchain to composition surfaces. It also takes in HWND, but it allocates a few things (namely composition device, target and visual) which needs to live as long as the swapchain or window, not sure yet how would I incorporate that with this library. But this is the gist of my idea.

As a code it looks something like this:

// This behavior is only supported on windows 8 and newer where
// composition is available
let mut swap_chain: *mut IDXGISwapChain1 = null_mut();
(*factory).CreateSwapChainForComposition(
    d3d11_device.raw_ptr() as *mut IUnknown,
    &desc,
    null_mut(),
    &mut swap_chain,
)
// Following resources are created according to this tutorial:
// https://docs.microsoft.com/en-us/archive/msdn-magazine/2014/june/windows-with-c-high-performance-window-layering-using-the-windows-composition-engine

// Create IDCompositionDevice
let mut ptr: *mut c_void = null_mut();
DCompositionCreateDevice(
    d3d11_device.raw_ptr() as *mut IDXGIDevice,
    &IDCompositionDevice::uuidof(),
    &mut ptr,
);
let composition_device = ComPtr::<IDCompositionDevice>::from_raw(ptr as _);

// Create IDCompositionTarget for the window
let mut ptr: *mut IDCompositionTarget = null_mut();
composition_device.CreateTargetForHwnd(hwnd as _, 1, &mut ptr); // <-- HWND GOES HERE 
let composition_target = ComPtr::from_raw(ptr);

// Create IDCompositionVisual and assign to swap chain
let mut ptr: *mut IDCompositionVisual = null_mut();
composition_device.CreateVisual(&mut ptr);
let composition_visual = ComPtr::from_raw(ptr);
composition_visual.SetContent(swap_chain as *mut IUnknown);

// Set the root as composition target and commit
composition_target.SetRoot(composition_visual.as_raw());
composition_device.Commit();

// composition_device, composition_target, composition_visual needs to be stored somewhere and live as long as the swapchain or window.
@kvark
Copy link
Member

kvark commented Mar 3, 2021

Interesting! Wouldn't the client of d3d12-rs want to manage IDCompositionDevice on their own? I.e. would it be feasible for d3d12 to conceal it entirely like you suggest here? I'd think that d3d12 being a low level binding library doesn't need to go as high wrt composition.

@Ciantic
Copy link
Author

Ciantic commented Mar 3, 2021

Yes, I don't have grand plan yet how to implement this. This is just opening, I tried to explain this on the matrix.

Maybe

create_swapchain_for_composition_hwnd(
        &self,
        composition_device: IDCompositionDevice,
        queue: CommandQueue,
        hwnd: HWND,
        desc: &SwapchainDesc,
    )  -> ??

I'm still trying to ingest all the frameworks around wgpu to get a sense of this. My bigger plan was to have support in the wgpu for transparent windows.

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

No branches or pull requests

3 participants