1 //
2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // SwapChainPanelNativeWindow.h: NativeWindow for managing ISwapChainPanel native window types.
8 
9 #ifndef LIBANGLE_RENDERER_D3D_D3D11_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
10 #define LIBANGLE_RENDERER_D3D_D3D11_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
11 
12 #include "libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h"
13 
14 #include <memory>
15 
16 namespace rx
17 {
18 class SwapChainPanelNativeWindow : public InspectableNativeWindow,
19                                    public std::enable_shared_from_this<SwapChainPanelNativeWindow>
20 {
21   public:
22     ~SwapChainPanelNativeWindow();
23 
24     bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) override;
25     HRESULT createSwapChain(ID3D11Device *device,
26                             IDXGIFactory2 *factory,
27                             DXGI_FORMAT format,
28                             unsigned int width,
29                             unsigned int height,
30                             bool containsAlpha,
31                             IDXGISwapChain1 **swapChain) override;
32 
33   protected:
34     HRESULT scaleSwapChain(const Size &windowSize, const RECT &clientRect) override;
35 
36     bool registerForSizeChangeEvents();
37     void unregisterForSizeChangeEvents();
38 
39   private:
40     ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> mSwapChainPanel;
41     ComPtr<ABI::Windows::UI::Core::ICoreDispatcher> mSwapChainPanelDispatcher;
42     ComPtr<IMap<HSTRING, IInspectable *>> mPropertyMap;
43     ComPtr<IDXGISwapChain1> mSwapChain;
44 };
45 
46 __declspec(uuid("8ACBD974-8187-4508-AD80-AEC77F93CF36")) class SwapChainPanelSizeChangedHandler
47     : public Microsoft::WRL::RuntimeClass<
48           Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
49           ABI::Windows::UI::Xaml::ISizeChangedEventHandler>
50 {
51   public:
SwapChainPanelSizeChangedHandler()52     SwapChainPanelSizeChangedHandler() {}
RuntimeClassInitialize(std::shared_ptr<InspectableNativeWindow> host)53     HRESULT RuntimeClassInitialize(std::shared_ptr<InspectableNativeWindow> host)
54     {
55         if (!host)
56         {
57             return E_INVALIDARG;
58         }
59 
60         mHost = host;
61         return S_OK;
62     }
63 
64     // ISizeChangedEventHandler
IFACEMETHOD(Invoke)65     IFACEMETHOD(Invoke)
66     (IInspectable *sender, ABI::Windows::UI::Xaml::ISizeChangedEventArgs *sizeChangedEventArgs)
67     {
68         std::shared_ptr<InspectableNativeWindow> host = mHost.lock();
69         if (host)
70         {
71             // The size of the ISwapChainPanel control is returned in DIPs.
72             // We are keeping these in dips because the swapchain created for composition
73             // also uses dip units. This keeps dimensions, viewports, etc in the same unit.
74             // XAML Clients of the ISwapChainPanel are required to use dips to define their
75             // layout sizes as well.
76             ABI::Windows::Foundation::Size newSize;
77             HRESULT result = sizeChangedEventArgs->get_NewSize(&newSize);
78             if (SUCCEEDED(result))
79             {
80                 host->setNewClientSize(newSize);
81             }
82         }
83 
84         return S_OK;
85     }
86 
87   private:
88     std::weak_ptr<InspectableNativeWindow> mHost;
89 };
90 
91 HRESULT GetSwapChainPanelSize(
92     const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel,
93     const ComPtr<ABI::Windows::UI::Core::ICoreDispatcher> &dispatcher,
94     Size *windowSize);
95 }  // namespace rx
96 #endif  // LIBANGLE_RENDERER_D3D_D3D11_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
97