1 //
2 // Copyright (c) 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, public std::enable_shared_from_this<SwapChainPanelNativeWindow>
19 {
20   public:
21     ~SwapChainPanelNativeWindow();
22 
23     bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) override;
24     HRESULT createSwapChain(ID3D11Device *device,
25                             IDXGIFactory2 *factory,
26                             DXGI_FORMAT format,
27                             unsigned int width,
28                             unsigned int height,
29                             bool containsAlpha,
30                             IDXGISwapChain1 **swapChain) override;
31 
32   protected:
33     HRESULT scaleSwapChain(const Size &windowSize, const RECT &clientRect) override;
34 
35     bool registerForSizeChangeEvents();
36     void unregisterForSizeChangeEvents();
37 
38   private:
39     ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> mSwapChainPanel;
40     ComPtr<ABI::Windows::UI::Core::ICoreDispatcher> mSwapChainPanelDispatcher;
41     ComPtr<IMap<HSTRING, IInspectable*>> mPropertyMap;
42     ComPtr<IDXGISwapChain1> mSwapChain;
43 };
44 
45 [uuid(8ACBD974-8187-4508-AD80-AEC77F93CF36)]
46 class SwapChainPanelSizeChangedHandler :
47     public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, ABI::Windows::UI::Xaml::ISizeChangedEventHandler>
48 {
49   public:
SwapChainPanelSizeChangedHandler()50     SwapChainPanelSizeChangedHandler() { }
RuntimeClassInitialize(std::shared_ptr<InspectableNativeWindow> host)51     HRESULT RuntimeClassInitialize(std::shared_ptr<InspectableNativeWindow> host)
52     {
53         if (!host)
54         {
55             return E_INVALIDARG;
56         }
57 
58         mHost = host;
59         return S_OK;
60     }
61 
62     // ISizeChangedEventHandler
IFACEMETHOD(Invoke)63     IFACEMETHOD(Invoke)(IInspectable *sender, ABI::Windows::UI::Xaml::ISizeChangedEventArgs *sizeChangedEventArgs)
64     {
65         std::shared_ptr<InspectableNativeWindow> host = mHost.lock();
66         if (host)
67         {
68             // The size of the ISwapChainPanel control is returned in DIPs.
69             // We are keeping these in dips because the swapchain created for composition
70             // also uses dip units. This keeps dimensions, viewports, etc in the same unit.
71             // XAML Clients of the ISwapChainPanel are required to use dips to define their
72             // layout sizes as well.
73             ABI::Windows::Foundation::Size newSize;
74             HRESULT result = sizeChangedEventArgs->get_NewSize(&newSize);
75             if (SUCCEEDED(result))
76             {
77                 host->setNewClientSize(newSize);
78             }
79         }
80 
81         return S_OK;
82     }
83 
84   private:
85     std::weak_ptr<InspectableNativeWindow> mHost;
86 };
87 
88 HRESULT GetSwapChainPanelSize(
89     const ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> &swapChainPanel,
90     const ComPtr<ABI::Windows::UI::Core::ICoreDispatcher> &dispatcher,
91     Size *windowSize);
92 }
93 #endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_
94