77#include " stdafx.h"
88#include " DCompPresenter.h"
99
10- DCompPresenter::~DCompPresenter ()
11- {
12- m_cmp.d3d11_gdi_tex ->Release ();
13- m_cmp.d3d11_front_buffer ->Release ();
14- m_cmp.d3d11_surface ->Release ();
15- m_cmp.dxgi_surface ->Release ();
16- m_cmp.d2d_dc ->Release ();
17- m_cmp.d3d_dc ->Release ();
18- m_cmp.comp_device ->Release ();
19- m_cmp.comp_target ->Release ();
20- m_cmp.dxgi_swapchain ->Release ();
21- m_cmp.d2d_factory ->Release ();
22- m_cmp.d2d_device ->Release ();
23- m_cmp.comp_visual ->Release ();
24- m_cmp.d2d1_bitmap ->Release ();
25- m_cmp.dxgi_device ->Release ();
26- m_cmp.d3d11_device ->Release ();
27- m_cmp.dxgi_adapter ->Release ();
28- m_cmp.dxgi_factory ->Release ();
29- }
30-
3110bool DCompPresenter::init (HWND hwnd)
3211{
3312 m_hwnd = hwnd;
@@ -36,21 +15,70 @@ bool DCompPresenter::init(HWND hwnd)
3615 GetClientRect (hwnd, &rect);
3716 m_size = {(UINT32)rect.right - rect.left , (UINT32)rect.bottom - rect.top };
3817
39- const auto cmp = create_composition_context (hwnd, m_size);
18+ CreateDXGIFactory2 (0 , IID_PPV_ARGS (dxgi_factory.GetAddressOf ()));
19+ dxgi_factory->EnumAdapters1 (0 , dxgi_adapter.GetAddressOf ());
20+
21+ D3D11CreateDevice (dxgi_adapter.Get (), D3D_DRIVER_TYPE_UNKNOWN, nullptr ,
22+ D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_SINGLETHREADED, nullptr , 0 ,
23+ D3D11_SDK_VERSION, &d3d11_device, nullptr , d3d_dc.GetAddressOf ());
24+
25+ d3d11_device->QueryInterface (dxgi_device.GetAddressOf ());
26+ dxgi_device->SetMaximumFrameLatency (1 );
27+
28+ DCompositionCreateDevice (dxgi_device.Get (), IID_PPV_ARGS (comp_device.GetAddressOf ()));
29+ comp_device->CreateTargetForHwnd (hwnd, true , comp_target.GetAddressOf ());
30+ comp_device->CreateVisual (comp_visual.GetAddressOf ());
31+
32+ DXGI_SWAP_CHAIN_DESC1 swapdesc{};
33+ swapdesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
34+ swapdesc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
35+ swapdesc.SampleDesc .Count = 1 ;
36+ swapdesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
37+ swapdesc.BufferCount = 2 ;
38+ swapdesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
39+ swapdesc.Width = m_size.width ;
40+ swapdesc.Height = m_size.height ;
41+
42+ dxgi_factory->CreateSwapChainForComposition (d3d11_device.Get (), &swapdesc, nullptr , dxgi_swapchain.GetAddressOf ());
43+ comp_visual->SetContent (dxgi_swapchain.Get ());
44+ comp_target->SetRoot (comp_visual.Get ());
45+
46+ D2D1CreateFactory (D2D1_FACTORY_TYPE_SINGLE_THREADED, {}, d2d_factory.GetAddressOf ());
47+ d2d_factory->CreateDevice (dxgi_device.Get (), d2d_device.GetAddressOf ());
48+ d2d_device->CreateDeviceContext (D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS,
49+ d2d_dc.GetAddressOf ());
50+
51+ D3D11_TEXTURE2D_DESC desc{};
52+ desc.Width = m_size.width ;
53+ desc.Height = m_size.height ;
54+ desc.MipLevels = 1 ;
55+ desc.ArraySize = 1 ;
56+ desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
57+ desc.SampleDesc = {.Count = 1 , .Quality = 0 };
58+ desc.Usage = D3D11_USAGE_DEFAULT;
59+ desc.BindFlags = D3D11_BIND_RENDER_TARGET;
60+ desc.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
61+
62+ d3d11_device->CreateTexture2D (&desc, nullptr , d3d11_gdi_tex.GetAddressOf ());
63+ d3d11_gdi_tex->QueryInterface (dxgi_surface.GetAddressOf ());
64+
65+ const UINT dpi = GetDpiForWindow (hwnd);
66+ const D2D1_BITMAP_PROPERTIES1 props =
67+ D2D1::BitmapProperties1 (D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
68+ D2D1::PixelFormat (DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), dpi, dpi);
4069
41- if (!cmp.has_value ())
42- {
43- return false ;
44- }
70+ d2d_dc->CreateBitmapFromDxgiSurface (dxgi_surface.Get (), props, d2d1_bitmap.GetAddressOf ());
71+ d2d_dc->SetTarget (d2d1_bitmap.Get ());
4572
46- m_cmp = cmp.value ();
73+ dxgi_swapchain->GetBuffer (1 , IID_PPV_ARGS (d3d11_front_buffer.GetAddressOf ()));
74+ dxgi_surface->QueryInterface (d3d11_surface.GetAddressOf ());
4775
4876 return true ;
4977}
5078
5179ID2D1RenderTarget *DCompPresenter::dc () const
5280{
53- return m_cmp. d2d_dc ;
81+ return d2d_dc. Get () ;
5482}
5583
5684D2D1_SIZE_U DCompPresenter::size ()
@@ -65,15 +93,15 @@ void DCompPresenter::resize(D2D1_SIZE_U size)
6593 m_size = size;
6694
6795 // 1. Release size-dependent resources that must be recreated after a swapchain resize
68- m_cmp. d2d_dc ->SetTarget (nullptr );
69- m_cmp. d2d1_bitmap -> Release ();
70- m_cmp. dxgi_surface -> Release ();
71- m_cmp. d3d11_front_buffer -> Release ();
72- m_cmp. d3d11_surface -> Release ();
73- m_cmp. d3d11_gdi_tex -> Release ();
96+ d2d_dc->SetTarget (nullptr );
97+ d2d1_bitmap. Reset ();
98+ dxgi_surface. Reset ();
99+ d3d11_front_buffer. Reset ();
100+ d3d11_surface. Reset ();
101+ d3d11_gdi_tex. Reset ();
74102
75103 // 2. Resize the swapchain buffers
76- m_cmp. dxgi_swapchain ->ResizeBuffers (2 , size.width , size.height , DXGI_FORMAT_B8G8R8A8_UNORM, 0 );
104+ dxgi_swapchain->ResizeBuffers (2 , size.width , size.height , DXGI_FORMAT_B8G8R8A8_UNORM, 0 );
77105
78106 // 3. Recreate the GDI-compatible texture at the new size
79107 D3D11_TEXTURE2D_DESC desc{};
@@ -87,47 +115,46 @@ void DCompPresenter::resize(D2D1_SIZE_U size)
87115 desc.BindFlags = D3D11_BIND_RENDER_TARGET;
88116 desc.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
89117
90- m_cmp. d3d11_device ->CreateTexture2D (&desc, nullptr , &m_cmp. d3d11_gdi_tex );
91- m_cmp. d3d11_gdi_tex ->QueryInterface (&m_cmp. dxgi_surface );
118+ d3d11_device->CreateTexture2D (&desc, nullptr , d3d11_gdi_tex. GetAddressOf () );
119+ d3d11_gdi_tex->QueryInterface (dxgi_surface. GetAddressOf () );
92120
93121 // 4. Recreate the D2D bitmap target from the new DXGI surface
94122 const UINT dpi = GetDpiForWindow (m_hwnd);
95123 const D2D1_BITMAP_PROPERTIES1 props =
96124 D2D1::BitmapProperties1 (D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
97125 D2D1::PixelFormat (DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), dpi, dpi);
98126
99- m_cmp. d2d_dc ->CreateBitmapFromDxgiSurface (m_cmp. dxgi_surface , props, &m_cmp. d2d1_bitmap );
100- m_cmp. d2d_dc ->SetTarget (m_cmp. d2d1_bitmap );
127+ d2d_dc->CreateBitmapFromDxgiSurface (dxgi_surface. Get () , props, d2d1_bitmap. GetAddressOf () );
128+ d2d_dc->SetTarget (d2d1_bitmap. Get () );
101129
102130 // 5. Re-acquire the front buffer and surface references from the resized swapchain
103- m_cmp. dxgi_swapchain ->GetBuffer (1 , IID_PPV_ARGS (&m_cmp. d3d11_front_buffer ));
104- m_cmp. dxgi_surface ->QueryInterface (&m_cmp. d3d11_surface );
131+ dxgi_swapchain->GetBuffer (1 , IID_PPV_ARGS (d3d11_front_buffer. GetAddressOf () ));
132+ dxgi_surface->QueryInterface (d3d11_surface. GetAddressOf () );
105133}
106134
107135void DCompPresenter::present ()
108136{
109137 // 1. Copy Direct2D graphics to the GDI-compatible texture
110- ID3D11Resource *d2d_render_target = nullptr ;
111- m_cmp.dxgi_surface ->QueryInterface (&d2d_render_target);
112- m_cmp.d3d_dc ->CopyResource (m_cmp.d3d11_gdi_tex , d2d_render_target);
113- d2d_render_target->Release ();
138+ Microsoft::WRL::ComPtr<ID3D11Resource> d2d_render_target;
139+ dxgi_surface->QueryInterface (d2d_render_target.GetAddressOf ());
140+ d3d_dc->CopyResource (d3d11_gdi_tex.Get (), d2d_render_target.Get ());
114141
115142 // 2. Copy the GDI-compatible texture to the swapchain's back buffer
116- ID3D11Resource *back_buffer = nullptr ;
117- m_cmp.dxgi_swapchain ->GetBuffer (0 , IID_PPV_ARGS (&back_buffer));
118- m_cmp.d3d_dc ->CopyResource (back_buffer, m_cmp.d3d11_gdi_tex );
119- back_buffer->Release ();
143+ Microsoft::WRL::ComPtr<ID3D11Resource> back_buffer;
144+ dxgi_swapchain->GetBuffer (0 , IID_PPV_ARGS (back_buffer.GetAddressOf ()));
145+ d3d_dc->CopyResource (back_buffer.Get (), d3d11_gdi_tex.Get ());
120146
121- m_cmp. dxgi_swapchain ->Present (0 , 0 );
122- m_cmp. comp_device ->Commit ();
147+ dxgi_swapchain->Present (0 , 0 );
148+ comp_device->Commit ();
123149}
124150
125151void DCompPresenter::blit (HDC hdc, RECT rect)
126152{
127153 // 1. Get our GDI-compatible D3D texture's DC
154+ Microsoft::WRL::ComPtr<IDXGISurface1> dxgi_surface;
155+ d3d11_gdi_tex->QueryInterface (dxgi_surface.GetAddressOf ());
156+
128157 HDC dc;
129- IDXGISurface1 *dxgi_surface;
130- m_cmp.d3d11_gdi_tex ->QueryInterface (&dxgi_surface);
131158 dxgi_surface->GetDC (false , &dc);
132159
133160 // 2. Blit our texture DC to the target DC, while preserving the alpha channel with AlphaBlend
@@ -136,5 +163,4 @@ void DCompPresenter::blit(HDC hdc, RECT rect)
136163
137164 // 3. Cleanup
138165 dxgi_surface->ReleaseDC (nullptr );
139- dxgi_surface->Release ();
140166}
0 commit comments