Skip to content

Commit b0b0a2b

Browse files
committed
Use ComPtr for all D3D11 pointers
1 parent edeba89 commit b0b0a2b

File tree

3 files changed

+43
-34
lines changed

3 files changed

+43
-34
lines changed

src/Files.App.CsWin32/Windows.Win32.ComPtr.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ public ComPtr(T* ptr)
2727
((IUnknown*)ptr)->AddRef();
2828
}
2929

30+
public void Attach(T* other)
31+
{
32+
if (_ptr is not null)
33+
((IUnknown*)_ptr)->Release();
34+
35+
_ptr = other;
36+
}
37+
3038
[MethodImpl(MethodImplOptions.AggressiveInlining)]
3139
public readonly T* Get()
3240
{
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
83f9dfee3c40c31ab2319cc0cf94c0f754aadf483ffe4aa6de16b1413ddb83c8
1+
2c50ef2c68ccdf705767f11a94caf940e0339e4bd2261961b6ff807fd4c12e44

src/Files.App/ViewModels/UserControls/Previews/ShellPreviewViewModel.cs

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -161,61 +161,62 @@ private unsafe bool ChildWindowToXaml(nint parent, UIElement presenter)
161161
D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_WARP,
162162
];
163163

164-
ID3D11Device* pD3D11Device = default;
165-
ID3D11DeviceContext* pD3D11DeviceContext = default;
166-
167-
foreach (var driveType in driverTypes)
164+
Windows.Win32.Foundation.HRESULT hr = default;
165+
using ComPtr<ID3D11Device> pD3D11Device = default;
166+
using ComPtr<ID3D11DeviceContext> pD3D11DeviceContext = default;
167+
using ComPtr<IDXGIDevice> pDXGIDevice = default;
168+
using ComPtr<IDCompositionDevice> pDCompositionDevice = default;
169+
using ComPtr<IUnknown> pControlSurface = default;
170+
ComPtr<IDCompositionVisual> pChildVisual = default; // Don't dispose this one, it's used by the compositor
171+
172+
// Create the D3D11 device
173+
foreach (var driverType in driverTypes)
168174
{
169-
var hr = PInvoke.D3D11CreateDevice(
170-
null,
171-
driveType,
172-
new(nint.Zero),
175+
hr = PInvoke.D3D11CreateDevice(
176+
null, driverType, new(nint.Zero),
173177
D3D11_CREATE_DEVICE_FLAG.D3D11_CREATE_DEVICE_BGRA_SUPPORT,
174-
null,
175-
0,
176-
7,
177-
&pD3D11Device,
178-
null,
179-
&pD3D11DeviceContext);
178+
null, /* FeatureLevels */ 0, /* SDKVersion */ 7,
179+
pD3D11Device.GetAddressOf(), null,
180+
pD3D11DeviceContext.GetAddressOf());
180181

181182
if (hr.Succeeded)
182183
break;
183184
}
184185

185-
if (pD3D11Device is null)
186+
if (pD3D11Device.IsNull)
186187
return false;
187188

188-
IDXGIDevice* pDXGIDevice = (IDXGIDevice*)pD3D11Device;
189-
if (PInvoke.DCompositionCreateDevice(pDXGIDevice, typeof(IDCompositionDevice).GUID, out var compositionDevicePtr).Failed)
190-
return false;
189+
Guid IID_IDCompositionDevice = typeof(IDCompositionDevice).GUID;
191190

192-
var pDCompositionDevice = (IDCompositionDevice*)compositionDevicePtr;
193-
IDCompositionVisual* pChildVisual = default;
194-
IUnknown* pControlSurface = default;
191+
// Create the DComp device
192+
pDXGIDevice.Attach((IDXGIDevice*)pD3D11Device.Get());
193+
hr = PInvoke.DCompositionCreateDevice(
194+
pDXGIDevice.Get(),
195+
&IID_IDCompositionDevice,
196+
(void**)pDCompositionDevice.GetAddressOf());
197+
if (hr.Failed)
198+
return false;
195199

196-
pDCompositionDevice->CreateVisual(&pChildVisual);
197-
pDCompositionDevice->CreateSurfaceFromHwnd(new(hwnd.DangerousGetHandle()), &pControlSurface);
198-
pChildVisual->SetContent(pControlSurface);
199-
if (pChildVisual is null || pControlSurface is null)
200+
// Create the visual
201+
hr = pDCompositionDevice.Get()->CreateVisual(pChildVisual.GetAddressOf());
202+
hr = pDCompositionDevice.Get()->CreateSurfaceFromHwnd(new(hwnd.DangerousGetHandle()), pControlSurface.GetAddressOf());
203+
hr = pChildVisual.Get()->SetContent(pControlSurface.Get());
204+
if (pChildVisual.IsNull || pControlSurface.IsNull)
200205
return false;
201206

207+
// Get the compositor and set the visual on it
202208
var compositor = ElementCompositionPreview.GetElementVisual(presenter).Compositor;
203209
outputLink = ContentExternalOutputLink.Create(compositor);
204210

205211
var target = outputLink.As<IDCompositionTarget>();
206-
target.SetRoot((nint)pChildVisual);
212+
target.SetRoot((nint)pChildVisual.Get());
207213

208214
outputLink.PlacementVisual.Size = new(0, 0);
209215
outputLink.PlacementVisual.Scale = new(1 / (float)presenter.XamlRoot.RasterizationScale);
210216
ElementCompositionPreview.SetElementChildVisual(presenter, outputLink.PlacementVisual);
211217

212-
pDCompositionDevice->Commit();
213-
214-
pControlSurface->Release();
215-
pDCompositionDevice->Release();
216-
pDXGIDevice->Release();
217-
pD3D11Device->Release();
218-
pD3D11DeviceContext->Release();
218+
// Commit the all pending DComp commands
219+
pDCompositionDevice.Get()->Commit();
219220

220221
var dwAttrib = Convert.ToUInt32(true);
221222

0 commit comments

Comments
 (0)