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 // InspectableNativeWindow.h: Host specific implementation interface for 8 // managing IInspectable native window types. 9 10 #ifndef LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_ 11 #define LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_ 12 13 #include "common/debug.h" 14 #include "common/platform.h" 15 16 #include "angle_windowsstore.h" 17 18 #include <EGL/eglplatform.h> 19 20 #include <windows.applicationmodel.core.h> 21 #undef GetCurrentTime 22 #if defined(ANGLE_ENABLE_WINDOWS_APP_SDK) 23 # include <microsoft.ui.dispatching.h> 24 # include <microsoft.ui.xaml.h> 25 # include <microsoft.ui.xaml.media.dxinterop.h> 26 #else 27 # include <windows.ui.xaml.h> 28 # include <windows.ui.xaml.media.dxinterop.h> 29 #endif 30 #include <wrl.h> 31 #include <wrl/wrappers/corewrappers.h> 32 33 using namespace Microsoft::WRL; 34 using namespace Microsoft::WRL::Wrappers; 35 using namespace ABI::Windows::Foundation; 36 using namespace ABI::Windows::Foundation::Collections; 37 38 #if defined(ANGLE_ENABLE_WINDOWS_APP_SDK) 39 using ISwapChainPanel = ABI::Microsoft::UI::Xaml::Controls::ISwapChainPanel; 40 #else 41 using ISwapChainPanel = ABI::Windows::UI::Xaml::Controls::ISwapChainPanel; 42 #endif 43 44 namespace rx 45 { 46 class InspectableNativeWindow 47 { 48 public: InspectableNativeWindow()49 InspectableNativeWindow() 50 : mSupportsSwapChainResize(true), 51 mSwapChainSizeSpecified(false), 52 mSwapChainScaleSpecified(false), 53 mSwapChainScale(1.0f), 54 mClientRectChanged(false), 55 mClientRect({0, 0, 0, 0}), 56 mNewClientRect({0, 0, 0, 0}) 57 { 58 mSizeChangedEventToken.value = 0; 59 } ~InspectableNativeWindow()60 virtual ~InspectableNativeWindow() {} 61 62 virtual bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) = 0; 63 virtual HRESULT createSwapChain(ID3D11Device *device, 64 IDXGIFactory2 *factory, 65 DXGI_FORMAT format, 66 unsigned int width, 67 unsigned int height, 68 bool containsAlpha, 69 IDXGISwapChain1 **swapChain) = 0; 70 getClientRect(RECT * rect)71 bool getClientRect(RECT *rect) 72 { 73 if (mClientRectChanged) 74 { 75 mClientRect = mNewClientRect; 76 } 77 78 *rect = mClientRect; 79 80 return true; 81 } 82 83 // setNewClientSize is used by the WinRT size change handler. It isn't used by the rest of 84 // ANGLE. setNewClientSize(const Size & newWindowSize)85 void setNewClientSize(const Size &newWindowSize) 86 { 87 // If the client doesn't support swapchain resizing then we should have already unregistered 88 // from size change handler 89 ASSERT(mSupportsSwapChainResize); 90 91 if (mSupportsSwapChainResize) 92 { 93 // If the swapchain size was specified then we should ignore this call too 94 if (!mSwapChainSizeSpecified) 95 { 96 mNewClientRect = clientRect(newWindowSize); 97 mClientRectChanged = true; 98 99 // If a scale was specified, then now is the time to apply the scale matrix for the 100 // new swapchain size and window size 101 if (mSwapChainScaleSpecified) 102 { 103 scaleSwapChain(newWindowSize, mNewClientRect); 104 } 105 } 106 107 // Even if the swapchain size was fixed, the window might have changed size. 108 // In this case, we should recalculate the scale matrix to account for the new window 109 // size 110 if (mSwapChainSizeSpecified) 111 { 112 scaleSwapChain(newWindowSize, mClientRect); 113 } 114 } 115 } 116 117 protected: 118 virtual HRESULT scaleSwapChain(const Size &windowSize, const RECT &clientRect) = 0; 119 RECT clientRect(const Size &size); 120 121 bool mSupportsSwapChainResize; // Support for IDXGISwapChain::ResizeBuffers method 122 bool mSwapChainSizeSpecified; // If an EGLRenderSurfaceSizeProperty was specified 123 bool mSwapChainScaleSpecified; // If an EGLRenderResolutionScaleProperty was specified 124 float mSwapChainScale; // The scale value specified by the EGLRenderResolutionScaleProperty 125 // property 126 RECT mClientRect; 127 RECT mNewClientRect; 128 bool mClientRectChanged; 129 130 EventRegistrationToken mSizeChangedEventToken; 131 }; 132 133 bool IsCoreWindow(EGLNativeWindowType window, 134 ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow = nullptr); 135 bool IsSwapChainPanel(EGLNativeWindowType window, 136 ComPtr<ISwapChainPanel> *swapChainPanel = nullptr); 137 bool IsEGLConfiguredPropertySet( 138 EGLNativeWindowType window, 139 ABI::Windows::Foundation::Collections::IPropertySet **propertySet = nullptr, 140 IInspectable **inspectable = nullptr); 141 142 HRESULT GetOptionalPropertyValue( 143 const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> &propertyMap, 144 const wchar_t *propertyName, 145 boolean *hasKey, 146 ComPtr<ABI::Windows::Foundation::IPropertyValue> &propertyValue); 147 148 HRESULT GetOptionalSizePropertyValue( 149 const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> &propertyMap, 150 const wchar_t *propertyName, 151 SIZE *value, 152 bool *valueExists); 153 154 HRESULT GetOptionalSinglePropertyValue( 155 const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable *>> &propertyMap, 156 const wchar_t *propertyName, 157 float *value, 158 bool *valueExists); 159 } // namespace rx 160 161 #endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_ 162