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